Domanda

Ho un'applicazione web scritta in Java (Spring, Hibernate / JPA, Struts2) in cui gli utenti possono caricare immagini e archiviarle nel file system. Vorrei ridimensionare quelle immagini in modo che siano di dimensioni coerenti per la visualizzazione sul sito. Quali librerie o funzioni integrate offriranno i migliori risultati? Nel prendere la mia decisione (in questo ordine) prenderò in considerazione i seguenti criteri:

  • Free / Open Source (essenziale)
  • Facile da implementare
  • Qualità dei risultati
  • Prestazioni
  • Dimensione dell'eseguibile
È stato utile?

Soluzione

Dai un'occhiata alla Java Image I / O API per leggere / scrivere l'immagine. Quindi utilizzare AffineTransform per ridimensionare.

Inoltre, ecco un esempio completo che utilizza java.awt.Image.

Altri suggerimenti

Consiglio vivamente di dare a imgscalr .

È rilasciato con una licenza Apache 2, ospitato su GitHub , già distribuito in una manciata di applicazioni Web, ha un molto semplice, ma API documentata pedanticamente , ha un codice che funziona in modo pedante circa 2 importanti bug di immagine nel JDK per te in modo trasparente che noterai sempre solo se inizi improvvisamente a ottenere "nero" immagini dopo un'operazione di scala o risultati orribili, ti offre i migliori risultati possibili disponibili in Java, è disponibile tramite Maven e ZIP ed è solo una singola classe.

L'uso di base è simile al seguente:

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

Questa è la chiamata più semplice in cui la libreria farà un'ipotesi migliore sulla qualità, onorerà le proporzioni dell'immagine e inserirà il risultato all'interno di un riquadro di delimitazione 320x320. NOTA, il riquadro di delimitazione è solo il massimo W / H utilizzato, poiché le proporzioni dell'immagine sono rispettate, l'immagine risultante lo onorerebbe ancora, diciamo 320x200.

Se vuoi sovrascrivere la modalità automatica e forzarla a darti il ??risultato più bello e anche applicare un filtro anti-alias molto lieve al risultato in modo che appaia ancora migliore (specialmente buono per le anteprime), quella chiamata sarebbe aspetto:

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

Questi sono solo esempi, l'API è ampia e copre tutto, dai casi d'uso semplicissimi a quelli molto specializzati. Puoi persino passare il tuo BufferedImageOps da applicare all'immagine (e la libreria corregge automaticamente il bug JDK BufferedImageOp di 6 anni per te!)

C'è molto di più nel ridimensionare con successo le immagini in Java che la libreria fa per te, ad esempio mantenendo sempre l'immagine in uno dei migliori tipi di immagine RGB o ARGB supportati mentre ci si lavora. Sotto le coperte la pipeline di elaborazione delle immagini Java2D ricade su una pipeline di software inferiore se il tipo di immagine utilizzato per qualsiasi operazione di immagine è scarsamente supportato.

Se tutto ciò sembrava un sacco di mal di testa, è un po '... ecco perché ho scritto la libreria e aperto la fonte, in modo che la gente potesse semplicemente ridimensionare le loro immagini e andare avanti con la propria vita senza preoccuparsene .

Spero che sia d'aiuto.

Cerca anche nella java-image-scaling . Ha creato immagini di qualità migliore rispetto a ImageIO.

So che questa è una domanda molto vecchia, ma ho ottenuto la mia soluzione usando l'API Java standard

import java.awt.*;
import java.awt.event.*;
import javax.imageio.*
import java.awt.image.*;

BufferedImage im, bi, bi2;
Graphics2D gfx;
int imWidth, imHeight, dstWidth, dstHeight;
int DESIRED_WIDTH = 500, DESIRED_HEIGHT = 500;

im = ImageIO.read(new File(filePath));
imWidth = im.getWidth(null);
imHeight = im.getHeight(null);

dstWidth = DESIRED_WIDTH;
dstHeight = (dstWidth * imHeight) / imWidth;

bi = new BufferedImage(dstWidth, dstHeight, im.getType());

gfx = bi.createGraphics();
gfx.drawImage(im, 0, 0, dstWidth, dstHeight, 0, 0, imWidth, imHeight, null);

bi2 = new BufferedImage(DESIRED_WIDTH, DESIRED_HEIGHT, im.getType());
gfx = bi2.createGraphics();

gfx.drawImage(bi, 0, 0, DESIRED_WIDTH, DESIRED_HEIGHT, null);

ImageIO.write(bi2, "jpg", new File(filePath));

Sono sicuro che può essere migliorato e adattato.

Lo strumento migliore per l'editing delle immagini è ImageMagick ed è open source.

Esistono due interfacce per il linguaggio Java:

JMagick che utilizza l'interfaccia JNI per ImageMagick

e

im4java che cos'è un'interfaccia della riga di comando per ImageMagick

Ho provato imgscalr rispetto allo standard Java 1.6 e non posso dire che sia migliore.

Quello che ho provato è

BufferedImage bufferedScaled = Scalr.resize(sourceImage, Method.QUALITY, 8000, height);

e

  Image scaled = sourceImage.getScaledInstance(-1, height, Image.SCALE_SMOOTH);
  BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null),  scaled.getHeight(null), BufferedImage.TYPE_INT_RGB);
  bufferedScaled.getGraphics().drawImage(scaled, 0, 0, null);

alcuni test di 5 minuti dal mio occhio hanno avuto l'impressione che la seconda cosa (puro Java 1.6) producesse risultati migliori.

Trovato per essere più veloce:

public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, final int targetHeight,
                                              final Object hint) {
    final int type = BufferedImage.TYPE_INT_RGB;
    int drawHeight = targetHeight;
    int drawWidth = targetWidth;
    final int imageWidth = img.getWidth();
    final int imageHeight = img.getHeight();
    if ((imageWidth <= targetWidth) && (imageHeight <= targetHeight)) {
        logger.info("Image " + imageWidth + "/" + imageHeight + " within desired scale");
        return img;
    }
    final double sar = ((double) imageWidth) / ((double) imageHeight);
    if (sar != 0) {
        final double tar = ((double) targetWidth) / ((double) targetHeight);
        if ((Math.abs(tar - sar) > .001) && (tar != 0)) {
            final boolean isSoureWider = sar > (targetWidth / targetHeight);
            if (isSoureWider) {
                drawHeight = (int) (targetWidth / sar);
            }
            else {
                drawWidth = (int) (targetHeight * sar);
            }
        }
    }
    logger.info("Scaling image from " + imageWidth + "/" + imageHeight + " to " + drawWidth + "/" + drawHeight);
    final BufferedImage result = new BufferedImage(drawWidth, drawHeight, type);
    try {
        final Graphics2D g2 = result.createGraphics();
        try {
            if (hint != null) {
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            }
            g2.drawImage(img, 0, 0, drawWidth, drawHeight, null);
        }
        finally {
            g2.dispose();
        }
        return result;
    }
    finally {
        result.flush();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top