J'ai besoin de redimensionner les fichiers PNG, JPEG et GIF. Comment puis-je faire cela en utilisant Java?
J'ai besoin de redimensionner les fichiers PNG, JPEG et GIF. Comment puis-je faire cela en utilisant Java?
Réponses:
Après avoir chargé l'image, vous pouvez essayer:
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 Je viens de publier (Apache 2, hébergé sur GitHub) une simple bibliothèque de mise à l'échelle d'image pour Java appelée imgscalr (disponible sur Maven central ).
La bibliothèque met en œuvre plusieurs approches différentes de la mise à l'échelle de l'image (y compris l'approche incrémentielle de Chris Campbell avec quelques améliorations mineures) et choisira soit l'approche la plus optimale pour vous si vous le lui demandez, soit vous donnera la plus rapide ou la meilleure apparence (si vous demandez-le).
L'utilisation est extrêmement simple, juste un tas de méthodes statiques. Le cas d'utilisation le plus simple est:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
Toutes les opérations conservent les proportions d'origine de l'image, donc dans ce cas, vous demandez à imgscalr de redimensionner votre image dans des limites de 200 pixels de large et 200 pixels de haut et par défaut, il sélectionnera automatiquement la meilleure approche et la plus rapide pour cela depuis 't spécifié.
Je me rends compte dès le départ que cela ressemble à de l'auto-promotion (c'est le cas), mais j'ai passé ma juste part de temps à googler exactement le même sujet et j'ai continué à proposer des résultats / approches / pensées / suggestions différents et j'ai décidé de m'asseoir et d'écrire un implémentation simple qui répondrait à 80 à 85% des cas d'utilisation où vous avez une image et que vous voulez probablement une vignette pour celle-ci - soit aussi vite que possible ou aussi belle que possible (pour ceux qui ont essayé, vous remarquerez faire un Graphics.drawImage même avec une interpolation BICUBIC vers une image suffisamment petite, cela ressemble toujours à une poubelle).
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. J'aime aussi ton chemin et je pense que c'est plus simple.
Thumbnailator est une bibliothèque de redimensionnement d'images open-source pour Java avec une interface fluide, distribuée sous la licence MIT.
J'ai écrit cette bibliothèque parce que créer des vignettes de haute qualité en Java peut être étonnamment difficile, et le code qui en résulte peut être assez compliqué. Avec Thumbnailator, il est possible d'exprimer des tâches assez compliquées en utilisant une API simple et fluide.
Un exemple simple
Pour un exemple simple, prendre une image et la redimensionner à 100 x 100 (en préservant le rapport hauteur / largeur de l'image d'origine) et l'enregistrer dans un fichier peut être réalisée en une seule instruction:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
Un exemple avancé
L'exécution de tâches de redimensionnement complexes est simplifiée grâce à l'interface fluide de Thumbnailator.
Supposons que nous voulions faire ce qui suit:
0.85
,thumbnail.
ajoutés au débutTraduit en Thumbnailator, nous pourrions effectuer les opérations ci-dessus avec les éléments suivants:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
Une note sur la qualité et la vitesse d'image
Cette bibliothèque utilise également la méthode de mise à l' échelle bilinéaire progressive mise en évidence dans Filthy Rich Clients de Chet Haase et Romain Guy afin de générer des vignettes de haute qualité tout en garantissant des performances d'exécution acceptables.
Vous n'avez pas besoin d'une bibliothèque pour cela. Vous pouvez le faire avec Java lui-même.
Chris Campbell a un excellent article détaillé sur la mise à l'échelle des images - voir cet article .
Chet Haase et Romain Guy ont également une description détaillée et très informative de la mise à l'échelle de l'image dans leur livre, Filthy Rich Clients .
Java Advanced Imaging est désormais open source et fournit les opérations dont vous avez besoin.
Si vous avez affaire à de grandes images ou que vous voulez un joli résultat, ce n'est pas une tâche triviale en java. Le faire simplement via une opération de redimensionnement via Graphics2D ne créera pas une vignette de haute qualité. Vous pouvez le faire en utilisant JAI, mais cela nécessite plus de travail que vous ne l'imaginez pour obtenir quelque chose qui semble bon et JAI a la mauvaise habitude de faire exploser votre JVM avec des erreurs OutOfMemory.
Je suggère d'utiliser ImageMagick comme exécutable externe si vous pouvez vous en tirer. C'est simple à utiliser et il fait le travail correctement pour que vous n'ayez pas à le faire.
L'API Java ne fournit pas de fonction de mise à l'échelle standard pour les images et de rétrogradation de la qualité d'image.
Pour cette raison, j'ai essayé d'utiliser cvResize de JavaCV mais cela semble poser des problèmes.
J'ai trouvé une bonne bibliothèque pour la mise à l'échelle d'image: ajoutez simplement la dépendance pour "java-image-scaling" dans votre pom.xml.
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
Dans le référentiel maven, vous obtiendrez la version récente pour cela.
Ex. Dans votre programme java
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
Vous pouvez essayer d'utiliser le système de traitement d'images GraphicsMagick avec im4java comme interface de ligne de commande pour Java.
GraphicsMagick présente de nombreux avantages, mais un pour tous:
Image Magick a été mentionnée. Il existe un projet frontal JNI appelé JMagick. Ce n'est pas un projet particulièrement stable (et Image Magick lui-même est connu pour changer beaucoup et même casser la compatibilité). Cela dit, nous avons une bonne expérience de l'utilisation de JMagick et d'une version compatible d'Image Magick dans un environnement de production pour effectuer une mise à l'échelle à un débit élevé et à un faible taux de latence. La vitesse était nettement meilleure qu'avec une bibliothèque graphique entièrement Java que nous avions précédemment essayée.
Utilisez simplement la réponse de Burkhard mais ajoutez cette ligne après avoir créé les graphiques:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
Vous pouvez également définir la valeur sur BICUBIC, cela produira une image de meilleure qualité mais c'est une opération plus coûteuse. Il existe d'autres conseils de rendu que vous pouvez définir, mais j'ai trouvé que l'interpolation produit l'effet le plus notable. Gardez à l'esprit que si vous souhaitez zoomer beaucoup, le code java sera très probablement très lent. Je trouve que les images plus grandes commencent à produire un décalage d'environ 300% de zoom, même avec tous les conseils de rendu définis pour optimiser la vitesse par rapport à la qualité.
Vous pouvez utiliser Marvin (pure infrastructure de traitement d'image Java) pour ce type d'opération: http://marvinproject.sourceforge.net
Plug-in Scale: http://marvinproject.sourceforge.net/en/plugins/scale.html
Il s'avère que l'écriture d'un scaler performant n'est pas anodine. Je l'ai fait une fois pour un projet open source: ImageScaler .
En principe, 'java.awt.Image # getScaledInstance (int, int, int)' ferait également l'affaire, mais il y a un bogue désagréable avec cela - reportez-vous à mon lien pour plus de détails.
J'ai développé une solution avec les classes disponibles gratuitement (AnimatedGifEncoder, GifDecoder et LWZEncoder) disponibles pour gérer les animations GIF.
Vous pouvez télécharger le fichier jgifcode et exécuter la classe GifImageUtil. Lien: http://www.jgifcode.com
vous pouvez utiliser le produit populaire suivant: miniature
Si vous ne voulez pas importer imgScalr comme la réponse @Riyad Kalla ci-dessus que j'ai testée fonctionne aussi bien, vous pouvez le faire à partir de la réponse de Peter Walser @Peter Walser sur un autre problème:
/**
* 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;
}
}
Essayez cette méthode suivante:
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);