Este es el cuarto artículo de la serie de filtros SVG, en el que Sara Soueidan le muestra cómo usar feComponentTransfer para crear un efecto de filtro de dos tonos.

La serie de artículos propuesta, "Efectos de filtrado SVG", de Sara Soueidan, un desarrollador independiente de interfaz UI / UX y autor de muchos artículos técnicos con sede en Líbano, se centra en el trabajo de los filtros SVG y consta de los siguientes artículos:
Efectos de filtrado SVG
- Efectos de filtrado SVG. Parte 1. Filtros SVG 101
- Efectos de filtrado SVG. Parte 2. Esquema de texto con feMorfología
- Efectos de filtrado SVG. Parte 3. Efecto de posterización de imagen usando feComponentTransfer
- Efectos de filtrado SVG. Parte 4. Imágenes a dos colores con feComponentTransfer .
- Efectos de filtro SVG: conformar texto a textura de superficie con feDisplacementMap
En un artículo anterior de esta serie, le presenté la primitiva feComponentTransfer , y la usamos para limitar el número de colores en una imagen para crear un efecto de posterización. En este artículo, veremos cómo se puede usar esta primitiva para crear un efecto de duotono , como Photoshop. También aprenderemos cómo usarlo para controlar la intensidad y el contraste de los colores de la imagen.
Breve resumen
Repite un poco.
La primitiva feComponentTransfer le permite cambiar cada uno de los componentes R, G, B y A presentes en el píxel. En otras palabras, feComponentTransfer proporciona una manipulación independiente de cada canal de color, así como del canal alfa, en el elemento de entrada .
Los componentes RGBA se modifican realizando diversos tipos de funciones en estos componentes. Para esto, cada componente tiene su propio elemento. Estos elementos componentes están anidados en feComponentTransfer . Para RGBA, estos son los elementos componentes feFuncR , feFuncG , feFuncB y feFuncA .
El atributo type se usa en un elemento componente para determinar el tipo de función que desea usar para modificar este componente. Actualmente hay cinco tipos de funciones disponibles: identidad , tabla , discreto , lineal y gamma . Este tipo de funciones se utilizan para cambiar los componentes RGBA (color y canal alfa) de una fuente de gráficos. Mencionamos que uno o más componentes pueden cambiarse al mismo tiempo y que los canales pueden cambiarse independientemente aplicando diferentes funciones a cada elemento componente.
<feComponentTransfer> <!-- The RED component --> <feFuncR type="identity | table | discrete | linear | gamma"></feFuncR> <!-- The GREEN component --> <feFuncG type="identity | table | discrete | linear | gamma"></feFuncG> <!-- The BLUE component --> <feFuncB type="identity | table | discrete | linear | gamma"></feFuncB> <!-- The ALPHA component --> <feFuncA type="identity | table | discrete | linear | gamma"></feFuncA> </feComponentTransfer>">
En un artículo anterior, aclaramos la función discreta y vimos cómo se puede usar para posterizar imágenes. En este artículo, comenzaremos utilizando la función de tabla para crear el efecto duotono, similar a lo que puede crear en Photoshop.
Crea un efecto de dos colores en Photoshop
No soy diseñador y no entiendo editores gráficos como Photoshop . Cuando quería crear un efecto de dos colores en SVG, primero busqué una forma de crear este efecto en un editor de gráficos para ver si podía replicarlo usando las operaciones de filtrado disponibles en SVG. Al final resultó que, los pasos para crear imágenes de dos colores en SVG son exactamente los mismos que en Photoshop.
El siguiente video es una versión acelerada de este tutorial que encontré en YouTube.
En este video, el diseñador crea un efecto de dos colores siguiendo estos pasos:
- Desaturar la imagen haciéndola sombras de gris.
- Compare la gama de tonos de gris con la nueva gama, que en lugar de blanco y negro en ambos extremos tiene dos colores diferentes que desea utilizar en un efecto de dos colores. En otras palabras, debe crear y utilizar un mapa de degradado con el que coincidan los tonos de gris.
Veamos cómo se pueden reproducir estos pasos en SVG.
Crea un efecto de dos colores en SVG
Para recrear este efecto en SVG, primero necesitamos blanquear la imagen. Esto se puede hacer usando la primitiva de filtro feColorMatrix .
Luego, necesitamos poder crear y pasar el mapa de gradiente al navegador para mostrar la nueva imagen en escala de grises.
Convierta imágenes en escala de grises con feColorMatrix
Con feColorMatrix, puede definir una matriz de color que determina la cantidad de rojo, verde y azul en su imagen. Al proporcionar una cantidad igual de estos tres componentes, creamos una matriz que convierte nuestra imagen en una versión de nosotros mismos en tonos de gris:
<svg viewBox="0 0 266 400"> <filter id="duotone"> <feColorMatrix type="matrix" values=".33 .33 .33 0 0 .33 .33 .33 0 0 .33 .33 .33 0 0 0 0 0 1 0"> </feColorMatrix> <!-- ... --> </filter> <image xlink:href="..." width="100%" x="0" y="0" height="100%" filter="url(#duotone)"></image> </svg>
En la siguiente figura, la imagen de la derecha es el resultado de aplicar el filtro anterior a la imagen de la izquierda:

Fig_1. El resultado (derecha) de convertir la imagen de la izquierda a escala de grises utilizando la operación de filtro feColorMatrix .
Puede aprender todo sobre feColorMatrix y cómo usarlo en este artículo de Una Kravets.
Ahora que nuestra imagen consiste esencialmente en un degradado gris, necesitamos crear un mapa de degradado de dos colores para mostrar el degradado gris.
Crear un mapa de degradado con la función de transferencia de componentes de tabla
En SVG, puede usar la primitiva feComponentTransfer con una tabla de tipos para crear un mapa de gradiente.
En el artículo anterior, vimos cómo puede hacer coincidir los colores de una imagen con la lista de colores proporcionada en el atributo tableValues utilizando la función discreta . El navegador utiliza nuestra lista de valores de tabla para crear rangos, que luego se utilizan para unir los colores con los valores que proporcionamos.
Al usar la función de tabla , también proporcionaremos valores de color en el atributo tableValues . Nuevamente, el navegador usará estos valores para hacer coincidir los colores de la imagen. Sin embargo, la forma en que el navegador muestra estos colores es diferente. En lugar de hacer coincidir los rangos de color con un valor de color discreto, creará un rango de color a partir de los valores proporcionados y luego asignará el rango de entrada a este nuevo rango.
Supongamos que queremos usar dos colores para nuestro efecto de dos tonos:

Fig_2. Los dos colores originales.
Estos dos colores se usarán para crear la pantalla de degradado:

Fig_3. Un gradiente creado por dos valores de color.
... a lo que vamos a hacer coincidir nuestro mapa en escala de grises.

Fig_4. Muestre un mapa de dos tonos con un degradado de dos colores.
Para usar estos colores en feComponentTransfer , necesitamos obtener los valores de los canales R, G y B de cada color. Dado que tableValues contiene valores fraccionarios, necesitamos convertir los valores RGB en fracciones. Los valores de color generalmente están en el rango [0.255]. Para convertirlos en fracciones, divídalos por 255.
Por ejemplo, el rosa tiene los siguientes valores RGB:
R: 254 G: 32 B: 141
Convirtiéndolos en una fracción, obtenemos:
R: 254/255 = .996078431 G: 32/255 = .125490196 B: 141/255 = .552941176
Del mismo modo para los valores amarillos obtenemos:
R: .984313725 G: .941176471 B: .478431373
Ahora que tenemos los valores de color, es hora de crear nuestro mapa de degradado. Mencionamos anteriormente que cuando proporcionamos valores de tabla para usar en la función de tabla , el navegador usará valores de tabla para crear el rango. Por lo tanto, comenzaremos proporcionando valores RGB de dos colores como valores RGB para elementos componentes:
<feComponentTransfer color-interpolation-filters="sRGB"> <feFuncR type="table" tableValues=".996078431 .984313725"></feFuncR> <feFuncG type="table" tableValues=".125490196 .941176471"></feFuncG> <feFuncB type="table" tableValues=".552941176 .478431373"></feFuncB> </feComponentTransfer>

En un artículo anterior, vimos que cuando se usa la función discreta , el navegador crea n rangos para n valores en tableValues . Cuando usamos la función de tabla , el navegador crea un rango n-1 para n valores. Porque proporcionamos dos valores de tabla para cada componente, lo que significa que obtendremos un rango ([rosa, amarillo]) para cada uno.
Ahora feComponentTransfer hará su trabajo: el navegador escaneará cada píxel de la fuente de la imagen en secuencia. Para cada píxel, recibirá el valor de los componentes rojo, verde y azul. Como nuestra imagen tiene sombras de gris, los valores R / G / B estarán en el rango [0, 1] = [negro, blanco] (0 - completamente negro, 1 - completamente blanco y sombras de gris entre ellos). Luego, el valor de cada componente se asignará al nuevo rango especificado en tableValues .
Entonces
- el valor del componente rojo se asignará al rango [.996078431, .984313725];
- el valor azul del componente se asignará al rango [.125490196, .941176471];
- el valor verde del componente se asignará al rango [.552941176, .478431373].
Por lo tanto, cuando el navegador pase por todos los píxeles de la imagen, reemplazará todos los valores RGB en el gradiente de escala de grises con los valores RGB de la pantalla de gradiente de dos colores. Como resultado, la imagen se convertirá en dos colores.

Fig_6. El resultado (derecha) de mostrar una imagen en escala de grises (izquierda) en nuestro mapa de degradado.
Nuestro código completo ahora se ve así:
<svg viewBox="0 0 266 400"> <filter id="duotone"> <!-- Grab the SourceGraphic (implicit) and convert it to grayscale --> <feColorMatrix type="matrix" values=".33 .33 .33 0 0 .33 .33 .33 0 0 .33 .33 .33 0 0 0 0 0 1 0"> </feColorMatrix> <!-- Map the grayscale result to the gradient map provided in tableValues --> <feComponentTransfer color-interpolation-filters="sRGB"> <feFuncR type="table" tableValues=".996078431 .984313725"></feFuncR> <feFuncG type="table" tableValues=".125490196 .941176471"></feFuncG> <feFuncB type="table" tableValues=".552941176 .478431373"></feFuncB> </feComponentTransfer> </filter> <image xlink:href=".." width="100%" x="0" y="0" height="100%" filter="url(#duotone)"></image> </svg>
Puedes jugar con la demo aquí:
Puede ir más allá y en lugar de proporcionar solo dos valores de color para el mapa de degradado, proporcione tres valores de color en tableValues , creando un mapa de degradado que tenga tres colores en lugar de dos.
Contraste y control de intensidad de color con función de transferencia gamma
Usando la función de transferencia de componentes gamma , podemos realizar la corrección gamma de nuestra fuente de gráficos. La corrección gamma es una función de controlar los niveles de luz de una imagen.
La función gamma tiene tres atributos que le permiten controlar la función de corrección gamma que se utilizará para controlar la iluminación: amplitud, exponente y compensación. Juntos, forman la siguiente función de transferencia:
C' = amplitude * pow(C, exponent) + offset
gamma se puede usar para controlar el contraste general de la imagen. El aumento del atributo exponente hace que las áreas oscuras sean más oscuras, mientras que el aumento del atributo de amplitud hace que las áreas claras brillen más. Y esto, a su vez, aumenta el contraste general de la imagen. El atributo de desplazamiento se usa para aumentar la intensidad de cada componente, y también afecta a la imagen completa: áreas claras y oscuras.
A veces, puede ser útil ajustar el contraste de las áreas oscuras y claras de la imagen si no obtiene la cantidad de "brillo" que le gustaría ver en la imagen.
Por ejemplo, si aplica el filtro de duotono de la sección anterior a la siguiente imagen, el resultado no será tan "en vivo" como nos gustaría:

Fig_7. El resultado del filtro de duotono.
La imagen de dos colores a la derecha se ve un poco pálida, y los colores son ligeramente borrosos. Quiero agregar contraste para que se vea más vibrante. Aumentemos un poco la amplitud y el exponente :
<feComponentTransfer color-interpolation-filters="sRGB"> <feFuncR type="gamma" exponent="1.5" amplitude="1.3" offset="0"></feFuncR> <feFuncG type="gamma" exponent="1.5" amplitude="1.3" offset="0"></feFuncG> <feFuncB type="gamma" exponent="1.5" amplitude="1.3" offset="0"></feFuncB> </feComponentTransfer>
Pude hacer que las áreas claras fueran más luminosas y las oscuras más intensas:

Fig_8. El resultado de la corrección gamma.
Por supuesto, esto es solo un ejemplo. Es posible que prefiera una versión más pálida de la imagen, especialmente para que se vea mejor con el texto en la parte superior. Creo que la corrección gamma es más útil para controlar el contraste de las imágenes en blanco y negro. Si aplico la misma operación de corrección de gamma a la versión en escala de grises de la imagen, obtengo una imagen más favorable:

Fig_9. El resultado de la corrección gamma para una imagen en escala de grises.
Por supuesto, puede hacer lo contrario y, en lugar de aumentar el contraste, puede aclarar un poco las áreas oscuras. En este caso, debe disminuir los valores de los atributos de amplitud y / o exponente , y no aumentarlos. El valor predeterminado para ambos es 1. El valor predeterminado del atributo de compensación es 0.
Juegue con los valores gamma en la siguiente demostración para comprender mejor cómo afectan el brillo y el contraste de la imagen:
Herramienta SVG de mapa de degradado
Yoksel ha estado jugando con filtros SVG durante algún tiempo y recientemente creó una herramienta visual fantástica que le permite cargar una imagen y aplicar varios efectos de dos o incluso tres tonos, y que genera un código de filtro SVG para usted, listo para ser copiado y pegado en cualquier ubicación deseada. Esta es una gran herramienta para explorar más a fondo feComponentTransfer .

Fig_10. Herramienta de filtro SVG de mapa de degradado de Yoksel.
La herramienta incluso le permite personalizar el efecto de escala de grises creado con feColorMatrix . En nuestro código, usamos un número igual de canales R, G y B para producir un efecto de escala de grises. Esta es una forma de hacer una imagen en escala de grises. Pero hay otras formas. Por ejemplo, puede crear un efecto de escala de grises para cada canal, lo que dará como resultado diferentes resultados de escala de grises para cada canal:

Fig_11. El resultado de crear una imagen en escala de grises de otras maneras.
Recomiendo jugar un poco con la herramienta y verificar cómo su selección de efectos cambia el código subyacente, ya que esta es una de las mejores maneras de aprender más sobre los filtros SVG.
Conclusión
La primitiva feComponentTransfer nos brinda un gran control sobre el color y los componentes alfa de las imágenes y nos permite crear efectos de clase Photoshop en la comodidad de nuestros editores de código.
En el próximo artículo de esta serie, veremos algunas primitivas más que nos permiten reproducir otro efecto de Photoshop utilizando casi los mismos pasos que en Photoshop, y mostraremos una vez más cómo SVG puede llevar el poder de los editores gráficos a la plataforma web. Aprenderemos cómo mezclar texto con el color y la textura de una imagen de fondo para obtener resultados atractivos. Quédate con nosotros