Necesito cambiar el tamaño de los archivos PNG, JPEG y GIF. ¿Cómo puedo hacer esto usando Java?
Necesito cambiar el tamaño de los archivos PNG, JPEG y GIF. ¿Cómo puedo hacer esto usando Java?
Respuestas:
Después de cargar la imagen puedes probar:
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
System.out.println("resizing...");
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
FWIW Acabo de lanzar (Apache 2, alojado en GitHub) una biblioteca simple de escalado de imágenes para Java llamada imgscalr (disponible en Maven central ).
La biblioteca implementa algunos enfoques diferentes para el escalado de imágenes (incluido el enfoque incremental de Chris Campbell con algunas mejoras menores) y elegirá el enfoque más óptimo para usted si así lo solicita, o le dará el aspecto más rápido o mejor (si usted pide eso).
El uso es muy simple, solo un montón de métodos estáticos. El caso de uso más simple es:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
Todas las operaciones mantienen las proporciones originales de la imagen, por lo que en este caso le está pidiendo a imgscalr que cambie el tamaño de su imagen dentro de los límites de 200 píxeles de ancho y 200 píxeles de alto y, de forma predeterminada, seleccionará automáticamente el enfoque más atractivo y más rápido para eso, ya que no era No especificado.
Al principio me doy cuenta de que esto parece autopromoción (lo es), pero pasé mi parte de tiempo buscando en Google exactamente el mismo tema y seguí sacando diferentes resultados / enfoques / pensamientos / sugerencias y decidí sentarme y escribir un Implementación simple que abordaría esos 80-85% de casos de uso en los que tiene una imagen y probablemente desee una miniatura para ella, ya sea lo más rápido posible o lo más atractivo posible (para aquellos que lo han intentado, notará haciendo una Graphics.drawImage incluso con interpolación BICUBIC a una imagen lo suficientemente pequeña, todavía parece basura).
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. También me gusta tu forma y creo que es más simple.
Thumbnailator es una biblioteca de redimensionamiento de imágenes de código abierto para Java con una interfaz fluida, distribuida bajo la licencia MIT.
Escribí esta biblioteca porque hacer miniaturas de alta calidad en Java puede ser sorprendentemente difícil, y el código resultante podría ser bastante complicado. Con Thumbnailator, es posible expresar tareas bastante complicadas utilizando una API fluida simple.
Un simple ejemplo
Para un ejemplo simple, tomar una imagen y cambiar su tamaño a 100 x 100 (preservando la relación de aspecto de la imagen original), y guardarla en un archivo se puede lograr en una sola declaración:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
Un ejemplo avanzado
La realización de tareas complejas de cambio de tamaño se simplifica con la interfaz fluida de Thumbnailator.
Supongamos que queremos hacer lo siguiente:
0.85
,thumbnail.
adjuntos al principioTraducido al Thumbnailator, podríamos realizar lo anterior con lo siguiente:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
Una nota sobre la calidad y la velocidad de la imagen.
Esta biblioteca también utiliza el método de escala progresiva bilineal resaltado en Filthy Rich Clients por Chet Haase y Romain Guy para generar miniaturas de alta calidad y garantizar un rendimiento de tiempo de ejecución aceptable.
No necesitas una biblioteca para hacer esto. Puedes hacerlo con el propio Java.
Chris Campbell tiene una excelente y detallada reseña sobre escalar imágenes: vea este artículo .
Chet Haase y Romain Guy también tienen una reseña detallada y muy informativa sobre el escalado de imágenes en su libro, Filthy Rich Clients .
Java Advanced Imaging ahora es de código abierto y proporciona las operaciones que necesita.
Si se trata de imágenes grandes o quiere un resultado atractivo, no es una tarea trivial en Java. Simplemente hacerlo a través de una operación de reescalado a través de Graphics2D no creará una miniatura de alta calidad. Puede hacerlo usando JAI, pero requiere más trabajo del que imagina para obtener algo que se vea bien y JAI tiene la desagradable costumbre de volar nuestra JVM con errores de OutOfMemory.
Sugiero usar ImageMagick como un ejecutable externo si puede salirse con la suya. Es simple de usar y hace el trabajo correctamente para que no tenga que hacerlo.
La API de Java no proporciona una función de escala estándar para imágenes y degrada la calidad de la imagen.
Debido a esto, traté de usar cvResize de JavaCV pero parece causar problemas.
Encontré una buena biblioteca para escalar imágenes: simplemente agregue la dependencia para "java-image-scaling" en su pom.xml.
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
En el repositorio de Maven obtendrá la versión más reciente para esto.
Ex. En su programa java
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
Puede intentar utilizar el sistema de procesamiento de imágenes GraphicsMagick con im4java como interfaz de línea de comando para Java.
GraphicsMagick ofrece muchas ventajas, pero una para todos:
Image Magick ha sido mencionado. Hay un proyecto front-end JNI llamado JMagick. No es un proyecto particularmente estable (y se sabe que Image Magick en sí misma cambia mucho e incluso rompe la compatibilidad). Dicho esto, hemos tenido una buena experiencia usando JMagick y una versión compatible de Image Magick en un entorno de producción para realizar escalado a un alto rendimiento y baja tasa de latencia. La velocidad fue sustancialmente mejor que con una biblioteca de gráficos de Java que probamos anteriormente.
Simplemente use la respuesta de Burkhard pero agregue esta línea después de crear los gráficos:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
También puede establecer el valor en BICUBIC, producirá una imagen de mejor calidad pero es una operación más costosa. Hay otras sugerencias de representación que puede establecer, pero he descubierto que la interpolación produce el efecto más notable. Tenga en cuenta que si desea acercarse mucho, el código Java probablemente será muy lento. Encuentro que las imágenes más grandes comienzan a producir un retraso de alrededor del 300% de zoom, incluso con todas las sugerencias de representación configuradas para optimizar la velocidad sobre la calidad.
Puede usar Marvin (marco de procesamiento de imágenes Java puro) para este tipo de operación: http://marvinproject.sourceforge.net
Complemento de escala: http://marvinproject.sourceforge.net/en/plugins/scale.html
Resulta que escribir un escalador de rendimiento no es trivial. Lo hice una vez para un proyecto de código abierto: ImageScaler .
En principio, 'java.awt.Image # getScaledInstance (int, int, int)' también haría el trabajo, pero hay un error desagradable con esto: consulte mi enlace para obtener más información.
He desarrollado una solución con las clases disponibles gratuitamente (AnimatedGifEncoder, GifDecoder y LWZEncoder) disponibles para manejar la animación GIF.
Puede descargar el jgifcode jar y ejecutar la clase GifImageUtil. Enlace: http://www.jgifcode.com
puedes usar el siguiente producto popular: thumbnailator
Si no desea importar imgScalr como @Riyad Kalla, la respuesta anterior que probé también funciona bien, puede hacer esto tomado de Peter Walser, responda @Peter Walser en otro tema:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/
public Icon getIcon(String name) {
Icon icon = null;
URL url = null;
ImageIcon imgicon = null;
BufferedImage scaledImage = null;
try {
url = getClass().getResource(name);
icon = new ImageIcon(url);
if (icon == null) {
System.out.println("Couldn't find " + url);
}
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon = new ImageIcon(scaledImage);
} catch (Exception e) {
System.out.println("Couldn't find " + getClass().getName() + "/" + name);
e.printStackTrace();
}
return imgicon;
}
public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);
int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
boolean scaleDown = scale < 1;
if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);
BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;
BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}
Pruebe este siguiente método:
ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);