Desarrollo de Software

Imágenes en escala de grises con HTML5

Habrás observado que las imágenes del menú superior y las de las redes sociales está en tonos grisáceos y si pasas el ratón por encima hace un efecto mostrando sus colores reales, haciendo el efecto inverso cuando quitas el ratón de encima. Vamos a ver cómo está hecho.

Menú principal

El código en JQuery es el siguiente:

function grayscale(src) {
	var canvas = document.createElement('canvas');
	var ctx = canvas.getContext('2d');
	var imgObj = new Image();
	imgObj.src = src;
	canvas.width = imgObj.width;
	canvas.height = imgObj.height;
	ctx.drawImage(imgObj, 0, 0);
	var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
	for(var y = 0; y < imgPixels.height; y++) {
		for(var x = 0; x < imgPixels.width; x++) {
			var i = (y * 4) * imgPixels.width + x * 4;
			var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
			imgPixels.data[i] = avg;
			imgPixels.data[i + 1] = avg + 25;
			imgPixels.data[i + 2] = avg;
		}
	}
	ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
	return canvas.toDataURL();
}
 
function initializeHover(object) {
  // Fade in images so there isn't a color "pop" document load and then on window load
	$(object).fadeIn(500);
 
	// clone image
	$(object).each(function() {
		var el = $(this);
		el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"998","opacity":"0"}).insertBefore(el).queue(function() {
			var el = $(this);
			el.parent().css({"width":this.width,"height":this.height});
			el.dequeue();
		});
		this.src = grayscale(this.src);
	});
 
	// Fade image
	$(object).mouseover(function() {
		$(this).parent().find('img:first').stop().animate({opacity:1}, 1000);
	});
	$('.img_grayscale').mouseout(function() {
		$(this).stop().animate({opacity:0}, 1000);
	});
}

Para utilizarlo tienes que tener una copia de jQuery, el código anterior, elegir las imágenes y añadir la siguiente línea:

initializeHover("ruta de las imágenes (DOM)");

Te comento como lo tengo exactamente en la web. En el fichero header.php tengo:

...
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.2/jquery.min.js'></script>
<script type='text/javascript' src='www.davidvalverde.com/js/common.js'></script>
...

y en el fichero common.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
window.onload = init;
 
function init() {
  initializeHover("header nav img");
}
 
// Grayscale w canvas method
function grayscale(src) {
	var canvas = document.createElement('canvas');
	var ctx = canvas.getContext('2d');
	var imgObj = new Image();
	imgObj.src = src;
	canvas.width = imgObj.width;
	canvas.height = imgObj.height;
	ctx.drawImage(imgObj, 0, 0);
	var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
	for(var y = 0; y < imgPixels.height; y++) {
		for(var x = 0; x < imgPixels.width; x++) {
			var i = (y * 4) * imgPixels.width + x * 4;
			var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
			imgPixels.data[i] = avg;
			imgPixels.data[i + 1] = avg + 25;
			imgPixels.data[i + 2] = avg;
		}
	}
	ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
	return canvas.toDataURL();
}
 
function initializeHover(object) {
  // Fade in images so there isn't a color "pop" document load and then on window load
	$(object).fadeIn(500);
 
	// clone image
	$(object).each(function() {
		var el = $(this);
		el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"998","opacity":"0"}).insertBefore(el).queue(function() {
			var el = $(this);
			el.parent().css({"width":this.width,"height":this.height});
			el.dequeue();
		});
		this.src = grayscale(this.src);
	});
 
	// Fade image
	$(object).mouseover(function() {
		$(this).parent().find('img:first').stop().animate({opacity:1}, 1000);
	});
	$('.img_grayscale').mouseout(function() {
		$(this).stop().animate({opacity:0}, 1000);
	});
}

Como puedes ver, en la línea 22 le añado 25 al valor medio calculado para darle a la imagen un tono verde.

Espero que te haya gustado. La idea y parte del código los he obtenido de webdesignerwall.com.

4 comentarios en “Imágenes en escala de grises con HTML5

Pon un comentario

Tu dirección de email no será publicada.

Puedes usar estas etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>