Comment redimensionner une image à l'aide de Java?

1. Introduction

Dans ce tutoriel, nous allons apprendre à redimensionner (mettre à l'échelle) une image à l'aide de Java. Nous explorerons à la fois les bibliothèques Java principales et tierces open-source qui offrent la fonction de redimensionnement d'image.

Il est important de mentionner que nous pouvons redimensionner les images à la fois vers le haut et vers le bas. Dans les exemples de code de ce didacticiel, nous redimensionnerons les images à des tailles plus petites car, en pratique, c'est le scénario le plus courant.

2. Redimensionner une image à l'aide de Core Java

Core Java propose les options suivantes pour redimensionner les images:

  • Redimensionner à l'aide de java.awt.Graphics2D
  • Redimensionner à l'aide de l' image # getScaledInstance

2.1. java.awt.Graphics2D

Graphics2D est la classe fondamentale pour le rendu de formes, de textes et d'images en 2 dimensions sur la plateforme Java.

Commençons par redimensionner une image à l'aide de Graphics2D :

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException { BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = resizedImage.createGraphics(); graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null); graphics2D.dispose(); return resizedImage; }

Voyons à quoi ressemble l'image avant et après le redimensionnement:

Le paramètre BufferedImage.TYPE_INT_RGB indique le modèle de couleur de l'image. Une liste complète des valeurs disponibles est disponible dans la documentation officielle Java BufferedImage .

Graphics2D accepte des paramètres supplémentaires appelés RenderingHints . Nous utilisons RenderingHints pour influencer différents aspects du traitement de l'image et surtout la qualité de l'image et le temps de traitement.

Nous pouvons ajouter un RenderingHint en utilisant la méthode setRenderingHint :

graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

Une liste complète des RenderingHints se trouve dans ce didacticiel Oracle.

2.2. Image.getScaledInstance ()

Cette approche utilisant Image est très simple et elle produit des images de qualité satisfaisante:

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException { Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT); BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); outputImage.getGraphics().drawImage(resultingImage, 0, 0, null); return outputImage; }

Voyons ce qui se passe avec une image de quelque chose de délicieux:

Nous pouvons également demander au mécanisme de mise à l'échelle d'utiliser l'une des approches disponibles en fournissant à la méthode getScaledInstance () un indicateur indiquant le type d'algorithme à utiliser pour nos besoins de rééchantillonnage d'image:

Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);

Tous les indicateurs disponibles sont décrits dans la documentation officielle de Java Image.

3. Imgscalr

Imgscalr utilise Graphic2D en arrière-plan. Il dispose d'une API simple avec quelques méthodes différentes pour le redimensionnement d'image.

Imgscalr nous fournit le meilleur résultat, le résultat le plus rapide ou un résultat équilibré en fonction de l'option de mise à l'échelle que nous choisissons. D'autres fonctionnalités de manipulation d'image sont également disponibles - comme celles pour le recadrage et la rotation. Voyons comment cela fonctionne dans un exemple simple.

Nous ajouterons la dépendance Maven suivante:

 org.imgscalr imgscalr-lib 4.2 

Vérifiez Maven Central pour la dernière version.

La façon la plus simple d'utiliser Imgscalr est:

BufferedImage simpleResizeImage(BufferedImage originalImage, int targetWidth) throws Exception { return Scalr.resize(originalImage, targetWidth); }

originalImage est la BufferedImage à redimensionner et targetWidth est la largeur d'une image de résultat. Cette approche conservera les proportions de l'image d'origine et utilisera les paramètres par défaut - Method.AUTOMATIC et Mode.AUTOMATIC .

Comment ça se passe avec une image de délicieux fruits? Voyons voir:

La bibliothèque permet également plusieurs options de configuration et gère la transparence de l'image en arrière-plan.

Les paramètres les plus importants sont:

  • mode - utilisé pour définir les modes de redimensionnement que l'algorithme utilisera. Par exemple, nous pouvons définir si nous souhaitons conserver les proportions de l'image (les options sont AUTOMATIC, FIT_EXACT, FIT_TO_HEIGHT et FIT_TO_WIDTH )
  • method - indique au processus de redimensionnement de sorte qu'il se concentre sur la vitesse, la qualité ou les deux. Les valeurs possibles sont AUTOMATIC, BALANCED, QUALITY, SPEED, ULTRA_QUALITY

Il est également possible de définir des propriétés de redimensionnement supplémentaires qui nous fourniront une journalisation ou demanderont à la bibliothèque de faire quelques modifications de couleur sur l'image (la rendre plus claire, plus sombre, en niveaux de gris, etc.).

Utilisons le paramétrage complet de la méthode resize () :

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception { return Scalr.resize(originalImage, Scalr.Method.AUTOMATIC, Scalr.Mode.AUTOMATIC, targetWidth, targetHeight, Scalr.OP_ANTIALIAS); }

Et maintenant, nous obtenons:

Imgscalr fonctionne avec tous les fichiers pris en charge par Java Image IO - JPG, BMP, JPEG, WBMP, PNG et GIF.

4. Thumbnailator

Thumbnailator est une bibliothèque de redimensionnement d'images open source pour Java qui utilise une mise à l'échelle bilinéaire progressive. Il prend en charge JPG, BMP, JPEG, WBMP, PNG et GIF.

We'll include it in our project by adding the following Maven dependency to our pom.xml:

 net.coobird thumbnailator 0.4.11 

Available dependency versions can be found on Maven Central.

It has a very simple API and allows us to set output quality in percentage:

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Thumbnails.of(originalImage) .size(targetWidth, targetHeight) .outputFormat("JPEG") .outputQuality(1) .toOutputStream(outputStream); byte[] data = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(data); return ImageIO.read(inputStream); }

Let's see how this smiling photograph looks before and after resizing:

It also has an option for batch processing:

Thumbnails.of(new File("path/to/directory").listFiles()) .size(300, 300) .outputFormat("JPEG") .outputQuality(0.80) .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

As Imgscalr, Thumblinator works with all files supported by Java Image IO – JPG, BMP, JPEG, WBMP, PNG, and GIF.

5. Marvin

Marvin is a handy tool for image manipulation and it offers a lot of useful basic (crop, rotate, skew, flip, scale) and advanced (blur, emboss, texturing) features.

As before, we'll add Maven dependencies needed for Marvin resizing:

 com.github.downgoon marvin 1.5.5 pom   com.github.downgoon MarvinPlugins 1.5.5 

Available Marvin dependency versions can be found on Maven Central, along with the Marvin Plugins versions.

The downside of Marvin is that it doesn't offer an additional scaling configuration. Also, the scale method requires an image and image clone which is a bit cumbersome:

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) { MarvinImage image = new MarvinImage(originalImage); Scale scale = new Scale(); scale.load(); scale.setAttribute("newWidth", targetWidth); scale.setAttribute("newHeight", targetHeight); scale.process(image.clone(), image, null, null, false); return image.getBufferedImageNoAlpha(); }

Let's now resize an image of a flower and see how it goes:

6. Best Practice

Image processing is an expensive operation in terms of resources, so picking the highest quality is not necessarily the best option when we don't really need it.

Let's see the performance of all of the approaches. We took one 1920×1920 px image, and scaled it to 200×200 px. The resulting observed times are as follows:

  • java.awt.Graphics2D – 34ms
  • Image.getScaledInstance() – 235ms
  • Imgscalr – 143ms
  • Thumbnailator – 547ms
  • Marvin – 361ms

De plus, lors de la définition de la largeur et de la hauteur de l'image cible, nous devons faire attention au rapport hauteur / largeur de l'image. De cette façon, l'image conservera ses proportions d'origine et ne sera pas étirée.

7. Conclusion

Cet article a illustré quelques façons de redimensionner une image en Java. Nous avons également appris combien de facteurs différents peuvent influencer le processus de redimensionnement.

Des exemples de code complets sont disponibles sur GitHub.