cambiar color de parte de una imagen con CSS

Cambiar el color de parte de una imagen

Si has usado Photoshop o algún otro programa de tratamiento de imágenes, puede que hayas empleado los modos de fusión de capas para conseguir colorear determinadas zonas de una imagen. Con el uso de una máscara para seleccionar la forma y una capa de color en modo “multiply” podemos colorear el área que deseemos. Ahora, con algunas de las nuevas propiedades de CSS3 podemos replicar este mismo efecto de forma dinámica en una página web.

capas en photoshop

En la imagen superior puedes ver un ejemplo del uso de las capas que permitiría conseguir este resultado. Solo cambiando el color de la capa en modo “multiply” vemos cambiar el color de la camiseta, colocada en una capa inferior.

Al igual que Photoshop, los principales navegadores soportan la fusión de capas en modo “multiply”. La única excepción importante la constituyen los navegadores de Microsoft, aunque los desarrolladores de la compañía ya han indicado que lo tienen bajo estudio y posiblemente lo implementarán para principios de 2018. En este estado de cosas ya no es descabellado plantearse hacer uso de ese modo de mezcla, ya que tiene un soporte mayoritario.

En esta ocasión vamos a centrarnos en cómo conseguir este efecto en los navegadores que soportan la propiedad CSS mix-blend-mode, que como ya he dicho son la mayoría, y más adelante ofreceremos una solución alternativa para otros navegadores.

Ponle la camiseta
<div id="tshirt_container">
	<img src="images/white-t-shirt.jpg" class="tshirt_layer" id="tshirt_layer_1">
	<img src="images/guy.png" class="tshirt_layer" id="tshirt_layer_2">	
</div>

Lo primero que hemos hecho es colocar la imagen del chico con la camiseta como un png con el hueco de la camiseta transparente, y debajo la camiseta sin color.

Usamos las posiciones y la propiedad z-index para colocar una sobre otra, y a la imagen del chico le añadimos la propiedad mix-blend-mode con el valor multiply.

#tshirt_container{
 position: relative;
 width: 300px;
 height: 450px;
}

#tshirt_container .tshirt_layer{
 position: absolute;
 display: table;
  width: 300px;
 height: 450px;
}

#tshirt_layer_1{
 z-index: 1;
}

#tshirt_layer_2{
	z-index: 2;
	-o-mix-blend-mode: multiply;
	-ms-mix-blend-mode: multiply;
	-moz-mix-blend-mode: multiply;
	mix-blend-mode: multiply;
	-webkit-mix-blend-mode: multiply;
}
Dale color

Llegados a este punto, ya podemos comprobar que con solo añadirle un color de fondo (background-color) a la imagen superior (#tshirt_layer_2), podemos colorear la camiseta.

#tshirt_layer_2{
	background-color: #7bd148;
}

También podemos usar un script que nos permita asignar dinámicamente el color de fondo a partir de una selección por parte del usuario. Existen multitud de selectores de color basados en jQuery o directamente en JavaScript que realizan esta tarea y puedes elegir el que mejor se adapte al uso que le vayas a dar.

Yo particularmente he pensado en su aplicación en una tienda, en la que un producto puede tener un número limitado de variaciones de color. Para ello he usado jQuery Simple Color Picker.

Deja que seleccionen

No hay problema si has decidido usar cualquier otro selector de color, ya que todo lo que hay que conseguir es permitir al usuario escoger un color y asignar la propiedad background-color de la imagen principal según el valor escogido.

Si vas a usar jQuery Simple Color Picker nos queda poco para tener nuestro selector funcionando. En su propia página de GitHub se muestra cómo hacerlo. Empezaremos por añadir un “select” con las opciones que necesitemos.

<select name="colorpicker-shortlist" id="colorpicker">
  <option value="#7bd148"">Green</option>
  <option value="#5484ed">Bold blue</option>
  <option value="#a4bdfc">Blue</option>
  <option value="#46d6db">Turquoise</option>
  <option value="#7ae7bf">Light green</option>
  <option value="#51b749">Bold green</option>
  <option value="#fbd75b">Yellow</option>
  <option value="#ffb878">Orange</option>
  <option value="#ff887c">Red</option>
  <option value="#dc2127">Bold red</option>
  <option value="#dbadff">Purple</option>
  <option value="#e1e1e1">Gray</option>
  <option value="#cabdbf">#cabdbf</option>
</select>

Solo nos quedaría cargar el script (ten presente que es dependiente de jQuery) e indicarle qué hacer

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.js"></script>

<script type="text/javascript" src="js/jquery.simplecolorpicker.js"></script>

<link rel="stylesheet" href="jquery.simplecolorpicker.css">

<script type="text/javascript">
$(document).ready(function() {

    // asigna valor por defecto
    $('select[name="colorpicker-shortlist"]').simplecolorpicker('selectColor', '#7bd148');
    $('#tshirt_layer_2').css('background-color', $('select[name="colorpicker-shortlist"]').val());

    //cambia el color según la selección
    $('select[name="colorpicker-shortlist"]').on('change', function() {
    	$('#tshirt_layer_2').css('background-color', $('select[name="colorpicker-shortlist"]').val());
    });

})
</script>

Puedes encontrar una explicación más detallada en la propia página del plugin. No nos vamos a extender más en él ya que para nuestro propósito podríamos haber usado cualquier otro.

El resultado

Veamos el resultado obtenido al ponerlo todo junto en una aplicación práctica de uso genérico.

t-shirt backgroundguy with t-shirt

La economía del método es clarísima. Hemos usado dos imágenes en lugar de trece. El dibujo de la camiseta, en este caso, forma parte de la misma imagen png del chico, pero no sería difícil usar una imagen independiente que también cargara dinámicamente en función de la selección del usuario.

¿Qué nos queda?

Bien, como ya sugerí en el párrafo anterior, basándose en estas técnicas se podrían implementar todas las variaciones de una tienda de camisetas usando como base muy pocas imágenes y colocando encima el dibujo seleccionado.

En los casos en los que hay muchas variaciones de color la ventaja es más que evidente. En el ejemplo de abajo vemos que solo dos imágenes sustituyen a 24 variaciones.

shoes backgroundshoes

Sin embargo, como dije con anterioridad, Explorer y Edge no producen el efecto deseado por su falta de soporte a la propiedad mix-blend-mode. Ambos cambiarán el color de fondo de la imagen según seleccionemos, pero se comportará de forma opaca y no se fusionará con la imagen inferior. Aunque se ha anunciado un futuro soporte por parte de Edge, en la actualidad esta es la situación.

Por ahora vamos a dejarlo aquí. Más adelante explicaremos la manera de conseguir el mismo efecto en esos navegadores. Para los que no puedan esperar puedo anticiparles que la solución cosiste en realizar un filtro multiply a través de una función aplicada sobre un elemento canvas.

Mientras encuentro tiempo para elaborar esa exlicación, con el siguiente botón puedes descargar todos los archivos necesarios para poner en práctica lo que te he contado en esta página. Espero que te sea de utilidad.

Actualización: Si estás interesado en una nueva versión que funciona en todos los navegadores, visita nuestra nueva entrada: “Colorear parte de una imagen con Canvas

Colorear parte de imagen con Canvas
Deep Learning