¿Cómo se crea una imagen en miniatura de un JPEG en Java?

votos
35

¿Alguien puede ayudarme con algún código para crear una miniatura para un JPEG en Java?

Soy nuevo en esto, por lo que una explicación paso a paso sería apreciada.

Publicado el 01/07/2009 a las 14:19
fuente por usuario
En otros idiomas...                            


12 respuestas

votos
62
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);

Esto creará una miniatura de 100x100 píxeles como un objeto de Imagen. Si desea volver a escribirlo en el disco, simplemente convierta el código a este:

BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, Image.SCALE_SMOOTH),0,0,null);
ImageIO.write(img, "jpg", new File("test_thumb.jpg"));

Además, si le preocupan los problemas de velocidad (el método descrito anteriormente es bastante lento si desea escalar muchas imágenes), use estos métodos y la siguiente declaración:

private BufferedImage scale(BufferedImage source,double ratio) {
  int w = (int) (source.getWidth() * ratio);
  int h = (int) (source.getHeight() * ratio);
  BufferedImage bi = getCompatibleImage(w, h);
  Graphics2D g2d = bi.createGraphics();
  double xScale = (double) w / source.getWidth();
  double yScale = (double) h / source.getHeight();
  AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
  g2d.drawRenderedImage(source, at);
  g2d.dispose();
  return bi;
}

private BufferedImage getCompatibleImage(int w, int h) {
  GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
  GraphicsDevice gd = ge.getDefaultScreenDevice();
  GraphicsConfiguration gc = gd.getDefaultConfiguration();
  BufferedImage image = gc.createCompatibleImage(w, h);
  return image;
}

Y luego llama:

BufferedImage scaled = scale(img,0.5);

donde 0.5 es la proporción de escala e img es una Imagen Buffered que contiene la imagen de tamaño normal.

Respondida el 01/07/2009 a las 14:24
fuente por usuario

votos
30

Como ya habrán descubierto "fácil" y "buen resultado de aspecto" son dos cosas muy diferentes. He encapsulado estos dos requisitos en una muy simple biblioteca de escalado de imagen java (licencia Apache 2) que sólo lo hace todo bien para usted.

Código de ejemplo para crear una imagen en miniatura se ve así:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 150);

Sus proporciones de la imagen son honrados, la biblioteca hace un mejor conjetura en el método que debe utilizar en función de la cantidad de cambio en la imagen debido a la ampliación (el más rápido, equilibrado o calidad) y los tipos de imágenes Java2D mejor apoyados siempre se utiliza para hacer la escala para evitar la emisión de resultados "negro" o de salida (por ejemplo, mirando las imágenes GIF excesivamente difuminado) realmente terribles.

Además, si desea forzar a la mejor salida posible miniatura mirando en Java, la llamada a la API se vería así:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                                       150, 100, Scalr.OP_ANTIALIAS);

No sólo va a utilizar la biblioteca de la Java2D recomienda escala incremental para el usuario que le da el mejor resultado parecido, sino que también se aplicará un efecto anti-aliasing opcional a la miniatura (ConvolveOp con un núcleo muy afinado) a cada tan ligeramente suavizar el las transiciones entre los valores de píxeles así que la imagen se vea más uniforme y no es nítida o de amapola como se podría haber visto cuando pasas de imágenes muy grandes a las más pequeñas.

Puede leer todos los comentarios en la biblioteca (el código en sí está muy doc'ed) para ver todos los diferentes errores de JDK que se trabajan alrededor de u optimizaciones que se realizan para mejorar el rendimiento o el uso de la memoria. He pasado mucho tiempo de sintonización de esta implementación y han tenido una gran cantidad de buenos comentarios de la gente que despliegan en aplicaciones web y otros proyectos de Java.

Respondida el 05/07/2011 a las 17:47
fuente por usuario

votos
12

Esta es la forma sencilla de crear una miniatura de 100 x 100 sin ningún estiramiento o sesgar en la imagen.

private  void saveScaledImage(String filePath,String outputFile){
    try {

        BufferedImage sourceImage = ImageIO.read(new File(filePath));
        int width = sourceImage.getWidth();
        int height = sourceImage.getHeight();

        if(width>height){
            float extraSize=    height-100;
            float percentHight = (extraSize/height)*100;
            float percentWidth = width - ((width/100)*percentHight);
            BufferedImage img = new BufferedImage((int)percentWidth, 100, BufferedImage.TYPE_INT_RGB);
            Image scaledImage = sourceImage.getScaledInstance((int)percentWidth, 100, Image.SCALE_SMOOTH);
            img.createGraphics().drawImage(scaledImage, 0, 0, null);
            BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
            img2 = img.getSubimage((int)((percentWidth-100)/2), 0, 100, 100);

            ImageIO.write(img2, "jpg", new File(outputFile));    
        }else{
            float extraSize=    width-100;
            float percentWidth = (extraSize/width)*100;
            float  percentHight = height - ((height/100)*percentWidth);
            BufferedImage img = new BufferedImage(100, (int)percentHight, BufferedImage.TYPE_INT_RGB);
            Image scaledImage = sourceImage.getScaledInstance(100,(int)percentHight, Image.SCALE_SMOOTH);
            img.createGraphics().drawImage(scaledImage, 0, 0, null);
            BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
            img2 = img.getSubimage(0, (int)((percentHight-100)/2), 100, 100);

            ImageIO.write(img2, "jpg", new File(outputFile));
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
Respondida el 11/04/2012 a las 08:34
fuente por usuario

votos
4

La biblioteca JMagick (y la implementación de ImageMagick en Java) tendrá lo que necesita.

Respondida el 01/07/2009 a las 14:26
fuente por usuario

votos
3

el código Java arriba (con la escala / métodos getCompatibleImage) funcionó muy bien para mí, pero cuando me implementado en un servidor, que dejó de funcionar, ya que el servidor no tenía pantalla asociada con él - cualquier otra persona con este problema se puede arreglar mediante el uso de : BufferedImage bi = new BufferedImage (w, h, BufferedImage.TYPE_INT_RGB);

en lugar de BufferedImage bi = getCompatibleImage (w, h);

y borrar el método getCompatibleImage

(Nota posterior - resulta que esto funciona muy bien para la mayoría de las imágenes, pero tengo un montón de mis companys departamento de marketing que son imágenes JPEG profundidad de color de 32 bits, y la biblioteca se produce una excepción formato de imagen no soportado por todos aquellos :( - - ImageMagick / JMagick están empezando a verse más atractivo)

Respondida el 22/07/2010 a las 01:04
fuente por usuario

votos
1

Sé que esto es un post bastante viejo. He estado buscando una solución para generar la miniatura de modo terminar con esta

Thumbnails.of(originalImage).scale(0.25).asBufferedImage();

si está utilizando para móviles sugeriría para establecer la escala de 0.45

Thumbnails.of(originalImage).scale(0.45).asBufferedImage();

https://github.com/coobird/thumbnailator

Este es sin duda mucho más rápido utilizando el Graphics2D que han probado las opciones de ambos.

Respondida el 05/04/2017 a las 12:13
fuente por usuario

votos
1

Tengo clase util writtena con métodos de hace años estáticas usando JAI. Java Advanced Imaging API es el API más fiable en Java para hacer frente a las imágenes. Es vector de interpolación es lo más parecido a Photoshop en el mundo Java. Aqui esta uno de ellos:

public static ByteArrayOutputStream resize(InputStream inputStream , int IMG_WIDTH,
        int IMG_HEIGHT) throws Exception {
    BufferedImage originalImage = ImageIO.read(inputStream);
    int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB
            : originalImage.getType();
    BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
            type);
    {
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
        g.dispose();
        g.setComposite(AlphaComposite.Src);

        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
    }
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ImageIO.write(resizedImage, "png", bos);
    return bos;

} 
Respondida el 04/09/2016 a las 01:45
fuente por usuario

votos
1

Una manera sencilla de crear una miniatura sin estirar o una biblioteca. Funciona con la transparencia en PNG, también.

public File createThumbnail(String imageUrl, String targetPath) {
    final int imageSize = 100;
    File thumbnail = new File(targetPath);

    try {
        thumbnail.getParentFile().mkdirs();
        thumbnail.createNewFile();
        BufferedImage sourceImage = ImageIO.read(new File(imageUrl));
        float width = sourceImage.getWidth();
        float height = sourceImage.getHeight();

        BufferedImage img2;
        if (width > height) {
            float scaledWidth = (width / height) * (float) imageSize;
            float scaledHeight = imageSize;

            BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
            Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
            img.createGraphics().drawImage(scaledImage, 0, 0, null);

            int offset = (int) ((scaledWidth - scaledHeight) / 2f);
            img2 = img.getSubimage(offset, 0, imageSize, imageSize);
        }
        else if (width < height) {
            float scaledWidth = imageSize;
            float scaledHeight = (height / width) * (float) imageSize;

            BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
            Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
            img.createGraphics().drawImage(scaledImage, 0, 0, null);

            int offset = (int) ((scaledHeight - scaledWidth) / 2f);
            img2 = img.getSubimage(0, offset, imageSize, imageSize);
        }
        else {
            img2 = new BufferedImage(imageSize, imageSize, sourceImage.getType());
            Image scaledImage = sourceImage.getScaledInstance(imageSize, imageSize, Image.SCALE_SMOOTH);
            img2.createGraphics().drawImage(scaledImage, 0, 0, null);
        }
        ImageIO.write(img2, "png", thumbnail);
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return thumbnail;
}
Respondida el 20/07/2016 a las 05:49
fuente por usuario

votos
1

Hay muchos marcos de procesamiento de imágenes disponibles que puede hacer esto con sólo unas pocas líneas. El ejemplo a continuación genera las miniaturas en diferentes resoluciones (dada una anchura como referencia) utilizando Marco de Marvin . Las tres imágenes en miniatura se generaron en 92 ms .

entrada:

introducir descripción de la imagen aquí

salida:

introducir descripción de la imagen aquí

introducir descripción de la imagen aquí

introducir descripción de la imagen aquí

import static marvin.MarvinPluginCollection.*;

MarvinImage image = MarvinImageIO.loadImage("./res/input.jpg");
MarvinImage scaledImage = new MarvinImage(1,1);

scale(image, scaledImage, 250);
MarvinImageIO.saveImage(scaledImage, "./res/output_x250.jpg");

scale(image, scaledImage, 150);
MarvinImageIO.saveImage(scaledImage, "./res/output_x150.jpg");

scale(image, scaledImage, 50);
MarvinImageIO.saveImage(scaledImage, "./res/output_x50.jpg");
Respondida el 30/05/2016 a las 11:13
fuente por usuario

votos
1

He usado Thumbnailator! Se solucionó mi problema con dos líneas de código.

https://github.com/coobird/thumbnailator

Respondida el 11/08/2015 a las 18:23
fuente por usuario

votos
1

He pasado por un blog de acuerdo a los que haya siguientes opciones -

  1. Para los archivos RGB simples utilizar ImageScalr. ImageIO clase se utiliza para archivos de lectura y ImageScalr para crear imágenes en miniatura
  2. Para apoyar RGB + CYMK, utilice ImageIO y API JAI (Java Advanced Imaging) para la lectura de archivos y ImageScalr para crear imágenes en miniatura.
  3. En caso de que no sabe qué formatos de archivo, modo de color que se va a tratar, la opción más segura es usar ImageMagick.

Aquí es enlace que da una respuesta completa con fragmentos de código.

Respondida el 03/06/2014 a las 06:15
fuente por usuario

votos
1

He creado una aplicación llamada fotovault (sourceforge.net) que puede subir imágenes y crear miniaturas en Java usando ImageJ apis.

Por favor, lea mi blog a continuación

http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-java-using-imagej-api

Respondida el 16/02/2014 a las 19:34
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more