Modificar Brillo y Contraste con Java 2D

Como podéis comprobar, en el blog comento sobre ciertos temas o problemas que van surgiendo durante nuestro trabajo diario y que damos solución mediante Java y Javascript (o cualquier otra tecnología, mayoritariamente orientada a la web). Hace poco publiqué un post sobre cómo realizar zoom en imágenes publicadas en la aplicación web. Este problema afortunadamente pudimos resolverlo mediante javascript y jQuery. Tras esto, el cliente nos propuso como requisito realizar ajustes de brillo y contraste sobre imágenes digitalizadas y publicadas en nuestra aplicación.  Lo primero que se nos ocurrió fue incorporar alguna librería javascript para abordar lo que nos proponían, pero no encontramos nada adecuado que funcionara en todos los navegadores (esperaremos a HTML5 y el objeto canvas). La otra opción era, obviamente, realizar una petición al servidor para que nos enviara la imagen transformada con los datos de brillo y contraste actualizados.

El lenguaje Java incorpora la librería Java2D, cuyo API proporciona un amplio conjunto de clases para la composición y transformación de la imagen. La solución consistía en realizar una petición al servidor para recargar la página y actualizar la imagen, de manera que en el atributo src de la imagen realizara una petición al servidor para obtener una nueva imagen transformada, pasando los nuevos parámetros para brillo y contraste:

<img width="687" height="960" style="position: absolute; top: 0px; left: 82px;" src="/MiApp/ImageServlet?accion=42&id_imagen=1&brillo=10.0&contrast=1.0" />

En la página incorporamos cinco botones: más brillo, más contraste, menos brillo, menos contraste y restablecer brillo y contraste originales. Establecemos una escala de manera que los valores que podamos asignar al brillo van desde -125 hasta 125 (por defecto 0) y para el contraste desde 0.0 hasta 2.0 (por defecto 1.0). Cada vez que pulsamos los botones de brillo actualizamos la página para que el valor del parámetro brillo, dentro del atributo src de la imagen, se incremente o decremente en 5 unidades (o lo que deseemos). Haremos lo mismo en el caso del contraste con una variación de +0.1 ó -0.1 unidad (también modificable). El botón restablecer deja los parámetros en 0.0 para el brillo y 1.0 para el contraste. En resumen, los botones recargan de nuevo la página, pasando los nuevos valores actualizados de brillo y contraste, aumentando o decrementando su valor en función del botón pulsado.

El controlador que sirve la imagen en el servidor (en el ejemplo de arriba sería el servlet ImageServlet cuando recupera el parámetro accion con el valor 42) recogerá dichos parámetros, y cargará la imagen en memoria desde el archivo de un modo similar a éste:

JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new BufferedInputStream(new FileInputStream(ruta)));
BufferedImage buf = decoder.decodeAsBufferedImage();

El parámetro ruta es la ruta a la imagen en el sistema de ficheros (he omitido cómo recuperar la ruta a partir del identificador de imagen pasado como parámetro). Una vez cargada la imagen invocaremos al método que realizará la transformación, pasando como parámetro la referencia a la imagen y los valores de brillo y contraste:

buf = brightContrastChange(buf, brillo, contraste);

Y el código fuente de la función es la siguiente:

private static BufferedImage brightContrastChange(BufferedImage bufferedImagen, Float brillo, Float contraste)
{
//Transformación de la imagen con nuevos valores brillo y contraste
BufferedImageOp operacion = new RescaleOp(contraste, brillo, null);
bufferedImagen = operacion.filter(bufferedImagen, null);
return bufferedImagen;
}

Únicamente nos queda escribir la imagen en el outputStream para enviarla al navegador:

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
encoder.encode(bufferedImage);
output.flush();

Siendo output el outputStream o flujo de salida. Obviamente estos son los pasos básicos, pero se pueden incorporar numerosas mejoras.

Una de ellas es la de obtener la imagen mediante una petición AJAX, sin necesidad de recargar la página para actualizar los parámetros brillo y contraste. Otra es la de mostrar una barra sobre la que podamos seleccionar un valor determinado sin saltos de 5 en 5 (brillo) o de 0.1 en 0.1 (contraste). Un componente que nos ayudó enormemente a acometer esta funcionalidad fue el slider de jquery.ui y que comentaré en otra entrada del blog próximamente.

2 opiniones en “Modificar Brillo y Contraste con Java 2D”

  1. hola, me podrías mandar un ejemplo de código de la modificación de brillo y contraste? muchas gracias.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *