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 laImageData
.ImageData.height
: Altura en píxeles de laImageData
.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
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter