¿Cómo cambiar el contraste de una imagen con HTML5?

- Andrés Cruz

In english

¿Cómo cambiar el contraste de una imagen con HTML5?

En este artículo veremos cómo aumentar o reducir el contraste de una imagen con HTML5; además hablaremos un poco de como sería el proceso para aumentar el brillo de una imagen; que es un caso similar.

Estos son algunos de los métodos, tecnologías y conceptos que van a ser utilizados para llevar a cabo el desarrollo de este ejercicio:

  • Canvas: Para utilizarlo como lienzo y dibujar una imagen.
  • getImageData(): Permite obtener data sobre la imagen dibujada en el Canvas (ImageData):
    • ImageData.width: Anchura en píxeles de la ImageData.
    • ImageData.height: Altura en píxeles de la ImageData.
    • ImageData.resolution: La densidad de píxeles que posee la imagen.
    • ImageData.data: Array de una dimensión que contiene la data en RGBA (en ese orden), con enteros entre 0-255; representa los colores que componen la imagen dibujada en el Canvas; en otras palabras; los valores de los píxeles que componen a la imagen dibujada en el Canvas.
    • img.onload: Evento que se manifiesta una vez que la imagen ha sido cargada.

La fórmula del contraste

Queda fuera del alcance de este artículo definir el contraste en toda su extensión; sin embargo podemos definir el contraste como una variación de intensidades que permite incrementar la luminosidad entre las zonas oscuras y claras de una imagen permitiendo un mejor enfoque y claridad de la imagen; la fórmula empleada a nivel de pixel será la siguiente:

valorNuevo = ( valorAnterior - 128) * tan(ángulo) + 128

En donde:

  • valorAnterior: Es el valor original de un píxel en la imagen.
  • ángulo: Calculamos el ángulo como:  Math.tan(val * Math.PI / 180.0);
    • val : El valor del campo de tipo rango manejado por el usuario.

Puedes obtener más información sobre la fórmula en el siguiente enlace: Generación de Imágenes.

Definiendo el HTML

Primero necesitaremos un Canvas; el cual utilizaremos como lienzo para pintar una imagen y poder manipularla a nivel de pixeles:

<canvas id="canvas">
	<p>Tu navegador no soporta Canvas.</p>
</canvas>

Un campo de tipo rango (type="range") para poder aumentar y decrementar el contraste fácilmente:

<input type="range" id="contrast" min="-90" max="90" step="5" value="0">

Definiendo el JavaScript

Variables globales:

	var canvas = document.getElementById('canvas');// canvas
	var ctx = canvas.getContext('2d'); // contexto
	var contrast = document.getElementById("contrast");// input de tipo rango
	var srcImg = "image.png";// imagen fuente

Primero es necesario crear un objeto de tipo image a la cual se le establece una imagen fuente que será utilizada para pintarla en el Canvas con el método drawImage():

	// nueva imagen
	img = new Image();
	img.src = srcImg;

	img.onload = function() {
	
		// reescalamos el canvas a las dimenciones de la imagen
		canvas.width = img.width;
		canvas.height = img.height;
	
		// dibujamos la imagen en el Canvas
		ctx.drawImage(this, 0, 0);
		
	};

La siguiente función permite aumentar el contraste de la imagen pintada en el Canvas:

	// aumenta el contraste
	function AddContrast(val) {

		//combino la formula para obtener el contraste con el valor obtenido del elemento ranges
		var contrast = Math.tan(val * Math.PI / 180.0);

		// reescalamos el canvas a las dimenciones de la imagen
		canvas.width = img.width;
		canvas.height = img.height;
	
		// dibujamos la imagen en el Canvas
		ctx.drawImage(img, 0, 0);
		
		// obtenemos el ImageData
		var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
		var pix = imgd.data;
		
		// cambiamos el contraste
		for (var i = 0, n = pix.length; i < n; i += 4) {
			//incremento los valores rojo, verde y azul de cada pixel
			pix[i] = rangeColor(128 + (pix[i] - 128) * contrast);
			pix[i + 1] = rangeColor(128 + (pix[i + 1] - 128) * contrast);
			pix[i + 2] = rangeColor(128 + (pix[i + 2] - 128) * contrast);
		}
		
		// retornamos la data modificada al Canvas
		ctx.putImageData(imgd, 0, 0);
	}

Analizando la función anterior...

Creamos un objeto de tipo Image y le asignamos una imagen fuente.

img = new Image();
img.src = srcImg;

Obtenemos el imageData del Canvas y se opera a nivel de píxeles con el ImageData.data:

// obtenemos el ImageData var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height); var pix = imgd.data;

Por último alteramos los valores de los pixeles agregando contraste a la imagen a los píxeles en su notación RGB:

        for (var i = 0, n = pix.length; i < n; i += 4) {
            //incremento los valores rojo, verde y azul de cada pixel
            pix[i] = rangeColor(128 + (pix[i] - 128) * contrast);
            pix[i + 1] = rangeColor(128 + (pix[i + 1] - 128) * contrast);
            pix[i + 2] = rangeColor(128 + (pix[i + 2] - 128) * contrast);
        }

Para asegurarnos de que el color no se salga del rango 0-255 empleamos la siguiente función:

// valida que el color este en un rango valido function rangeColor(pix) {    if (pix < 0)        pix = 0;    if (pix > 255)        pix = 255;    return pix; }

El brillo

En cuanto al brillo, el mismo consiste en sumar una constante (K) que se encuentre en el rango 0-255; así que con tan solo modificar esta sección de código:

        for (var i = 0, n = pix.length; i < n; i += 4) {
            //incremento los valores rojo, verde y azul de cada pixel
            pix[i] = rangeColor(128 + (pix[i] - 128) * contrast);
            pix[i + 1] = rangeColor(128 + (pix[i + 1] - 128) * contrast);
            pix[i + 2] = rangeColor(128 + (pix[i + 2] - 128) * contrast);
        }

Por esta otra:

        for (var i = 0, n = pix.length; i < n; i += 4) {
            //cambio los valores rojo, verde y azul de cada pixel
            pix[i] = rangeColor(pix[i] + K);
            pix[i + 1] = rangeColor(pix[i + 1] + K);
            pix[i + 2] = rangeColor(pix[i + 2] + K);
        }

Podrás cambiar fácilmente el brillo de una imagen con solo HTML5; la constante K puede ser obtenida a partir de un campo de tipo rango como en el caso del contraste:

<input type="range" id="brightness" min="0" max="255" step="1" value="0">

Enlaces de Interés

Resultado Final

Ver demo Descargar Fuente

Acepto recibir anuncios de interes sobre este Blog.

En este artículo veremos cómo aumentar o reducir el contraste de una imagen con HTML5; además hablaremos un poco de como sería el proceso para aumentar el brillo de una imagen; que es un caso similar.

- Andrés Cruz

In english