Obtener el ancho y alto, escalar y convertir a otro formato imágenes con Java
Escrito por
el .
java
planeta-codigo
Enlace permanente
Comentarios
Las aplicaciones que tratan con imágenes es posible que necesiten conocer algunos datos de la imagen como anchura y altura, realizar algunas operaciones de manipulación básicas como escalado y conversión entre formatos. El propio JDK de Java ofrece algunas clases y soporta varios de los formatos más comunes de imagen. Para usos más avanzados hay que recurrir a librerías y si no fueran suficientes a comandos del sistema más avanzados.
El lenguaje de programación Java es un lenguaje de propósito general con el que es posible realizar cualquier tarea. Sin embargo, Java como lenguaje o plataforma aparte de Android el mayor uso que se le da es para aplicaciones y servicios en el lado del servidor.
Una de las necesidades que pueden surgir es escalar una imagen o cambiarle de formato, aunque Java solo ofrece un soporte básico para el tratamiento de imágenes, hay varias librerías pero pocas bien mantenidas y con buen soporte, si ni una librería ofrece la funcionalidad deseada en el caso más extremo se puede invocar a un proceso del sistema que ofrezca la funcionalidad com ImageMagick o FFmpeg.
La conversión y cambio de formato es un proceso costoso en CPU y memoria ya que requieren cargar la imagen en memoria más si las imágenes a tratar son muy grandes, de varias decenas de megabytes.
El propio JDK ofrece en su API soporte para los formatos de imágenes más comunes y algunas manipulaciones de imagen, hay varias librerías Java para la manipulación de imágenes y finalmente están los comandos del sistema.
- Cómo crear miniaturas o vistas previas de imágenes con ImageMagick
- Comando para convertir imágenes JPEG y PNG a WebP
Contenido del artículo
Formatos de imágenes
Hay varios formatos de imágenes que se pueden categorizar en dos grandes grupos: imágenes sin pérdida o con pérdida. Los formatos sin pérdida son más fieles a la imagen original pero con mayor tamaño que la equivalente en un formato con pérdida de calidad, en las imágenes con pérdida de calidad los algoritmos tratan de que visualmente la pérdida sea lo menos apreciable posible con un tamaño de imagen significativamente menor.
El formato png es un formato sin pérdida que ofrece buenos resultados para capturas de pantalla del ordenador. Para fotos el formato jpg ofrece un archivo de tamaño significativamente más reducido con una calidad bastante fiel al original.
Más recientemente han surgido nuevos formatos de imagen que utilizan otros algoritmos para la reducción de tamaño heic y heif utilizan el algoritmo con coste de licencia de x265 y el formato sin coste de licencia webp que ofrece similar o mejor resultado que el x265 que además soporta imágenes sin pérdida.
Procesar imágenes con Java
En el propio JDK hay varias clases para la utilización de imágenes en el paquete java.awt.
Formatos de imagen soportados
Los formatos de imagen soportados se pueden obtener mediante código y son extensibles añadiendo librerías al classpath, es posible que un formato se soporte en modo lectura pero no en escritura.
|
|
|
|
En esta lista de formatos aparece webp como formato soportados en la lectura porque en el ejemplo de código está incluida la librería de TwelveMonkeys que añade el soporte para la lectura de webp.
|
|
Lectura y escritura de una imagen
La clase que representa una imagen en Java es BufferedImage que se obtiene al leer el archivo del sistema de archivos o el InputStream, para la lectura y la escritura está la clase ImageIO.
|
|
La imagen en formato jpg tiene un tamaño de 192 KB y en formato webp tiene un tamaño de 80 KB, menos de la mitad en webp con una calidad similar.
Obtener el ancho y alto de una imagen
Una vez obtenida una instancia de BufferedImage esta clase ofrece métodos para conocer el ancho y alto de la imagen y a partir de estos la proporción o aspect ratio entre ambos valores.
|
|
|
|
Escalar una imagen
Escalar una imagen consiste en cambiar de tamaño a la imagen, normalmente el escalado se realiza conservando la proporción de anchura y altura para no distorsionar la imagen original.
El escalado suele realizarse para reducir la imagen con lo que se perderá información o píxeles, dependiendo del algoritmo de escalado aplicado la calidad y tamaño de la imagen resultante es diferente. En un escalado que implica reducir el tamaño los bytes de la imagen escalada serán menores.
|
|
Dependiendo de las opciones empleadas en el escalado la calidad y tamaño resultante es diferente y hay que conocerlas. Utilizando una librería permite realizar la operación de escalado con mejor calidad.
Cambiar el formato de una imagen
Cambiar de formato a una imagen es otra operación común, por ejemplo convertir al formato webp que ofrece una calidad mejor en el mismo tamaño o un significativo reducción de tamaño que puede llegar al más del 50% con una calidad similar.
Una vez cargada la imagen en un BufferedImage es posible escribir la imagen a un archivo en cualquier otro formato de escritura soportado.
|
|
Librerías de terceros
Hay varias librerías que añaden o facilitan algunas funcionalidades sobre la API de Java. Thuilmator permite realizar escalados de imágenes de una forma más sencilla que la API de Java.
|
|
Otra librería es TwelveMonkeys que añade soporte para algunos formatos de imagen como webp.
|
|
El tamaño de la imagen escalada por el código Java es de 28 KB, el tamaño de la imagen de Thuilmator es de 38 KB y el tamaño de TwelveMonkeys es de 26 KB con algunas pequeñas diferencias apreciables en el resultado de cada una de ellas.
Usando ImageMagick
Las funcionalidades de Java y de las librerías de Java para casos avanzados no son suficientes. El software de ImageMagick ofrece a través de un comando muchas más opciones para la manipulación de imágenes. El inconveniente de ImageMagick es que para ser usado desde Java requiere instalar el comando en el sistema. El uso de ImageMagick desde Java es como la invocación de cualquier otro proceso del sistema, es posible pasar la imagen a manipular por la entrada estándar del sistema y obtener la imagen resultado por la salida estándar del sistema del proceso.
Si no hay ninguna librería Java que proporcione soporte para la escritura a formato webp el siguiente código invoca el comando convert de ImageMagick para realizar la conversión. El tamaño de la imagen en formato webp es de 80 KB que son muchos menos que en cualquiera de los formatos jpg generados con Java de los casos anteriores.
|
|
|
|
El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:./gradlew run