Wie kann ich die Größe eines Bildes mit Java ändern?

1. Einleitung

In diesem Tutorial lernen wir, wie man die Größe eines Bildes mit Java ändert (skaliert). Wir werden sowohl Java-Kernbibliotheken als auch Open-Source-Bibliotheken von Drittanbietern untersuchen, die die Funktion zum Ändern der Bildgröße bieten.

Es ist wichtig zu erwähnen, dass wir Bilder sowohl nach oben als auch nach unten skalieren können. In den Codebeispielen in diesem Lernprogramm werden wir die Größe von Bildern auf kleinere Größen ändern, da dies in der Praxis das häufigste Szenario ist.

2. Ändern Sie die Größe eines Bildes mit Core Java

Core Java bietet die folgenden Optionen zum Ändern der Bildgröße:

  • Ändern Sie die Größe mit java.awt.Graphics2D
  • Ändern Sie die Größe mit Image # getScaledInstance

2.1. java.awt.Graphics2D

Graphics2D ist die grundlegende Klasse zum Rendern zweidimensionaler Formen, Texte und Bilder auf der Java-Plattform.

Beginnen wir mit der Größenänderung eines Bildes mit 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; }

Mal sehen, wie das Bild vor und nach der Größenänderung aussieht:

Der Parameter BufferedImage.TYPE_INT_RGB gibt das Farbmodell des Bildes an. Eine vollständige Liste der verfügbaren Werte finden Sie in der offiziellen Java BufferedImage- Dokumentation.

Graphics2D akzeptiert zusätzliche Parameter namens RenderingHints . Wir verwenden RenderingHints , um verschiedene Bildverarbeitungsaspekte und vor allem die Bildqualität und die Verarbeitungszeit zu beeinflussen.

Wir können einen RenderingHint mit der setRenderingHint- Methode hinzufügen :

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

Eine vollständige Liste der RenderingHints finden Sie in diesem Oracle-Tutorial.

2.2. Image.getScaledInstance ()

Dieser Ansatz mit Image ist sehr einfach und erzeugt Bilder von zufriedenstellender Qualität:

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; }

Mal sehen, was mit einem Bild von etwas Leckerem passiert:

Wir können den Skalierungsmechanismus auch anweisen, einen der verfügbaren Ansätze zu verwenden, indem wir der Methode getScaledInstance () ein Flag bereitstellen, das den Typ des Algorithmus angibt, der für unsere Anforderungen an das Resampling von Bildern verwendet werden soll:

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

Alle verfügbaren Flags sind in der offiziellen Java Image-Dokumentation beschrieben.

3. Imgscalr

Imgscalr verwendet Graphic2D im Hintergrund. Es verfügt über eine einfache API mit einigen verschiedenen Methoden zur Größenänderung von Bildern.

Imgscalr liefert uns entweder das am besten aussehende Ergebnis, das schnellste Ergebnis oder ein ausgewogenes Ergebnis, abhängig von der von uns ausgewählten Skalierungsoption. Es stehen auch andere Bildbearbeitungsfunktionen zur Verfügung - beispielsweise zum Zuschneiden und Drehen. Lassen Sie uns in einem einfachen Beispiel zeigen, wie es funktioniert.

Wir werden die folgende Maven-Abhängigkeit hinzufügen:

 org.imgscalr imgscalr-lib 4.2 

Überprüfen Sie Maven Central auf die neueste Version.

Der einfachste Weg, Imgscalr zu verwenden, ist:

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

Dabei ist originalImage das BufferedImage , dessen Größe geändert werden soll, und targetWidth die Breite eines Ergebnisbilds. Bei diesem Ansatz werden die ursprünglichen Bildproportionen beibehalten und Standardparameter verwendet - Method.AUTOMATIC und Mode.AUTOMATIC .

Wie geht es mit einem Bild von köstlichen Früchten? Wir werden sehen:

Die Bibliothek ermöglicht auch mehrere Konfigurationsoptionen und behandelt die Bildtransparenz im Hintergrund.

Die wichtigsten Parameter sind:

  • mode - wird verwendet, um die Größenänderungsmodi zu definieren, die der Algorithmus verwenden wird. Zum Beispiel können wir definieren, ob wir Proportionen des Bildes behalten möchten (Optionen sind AUTOMATISCH, FIT_EXACT, FIT_TO_HEIGHT und FIT_TO_WIDTH ).
  • Methode - Weist den Größenänderungsprozess an, sodass der Fokus auf Geschwindigkeit, Qualität oder beidem liegt. Mögliche Werte sind AUTOMATIC, BALANCED, QUALITY, SPEED, ULTRA_QUALITY

Es ist auch möglich, zusätzliche Größenänderungseigenschaften zu definieren, die uns die Protokollierung ermöglichen, oder die Bibliothek anzuweisen, einige Farbänderungen am Bild vorzunehmen (heller, dunkler, Graustufen usw.).

Verwenden wir die vollständige Parametrisierung der resize () -Methode:

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); }

Und jetzt bekommen wir:

Imgscalr funktioniert mit allen Dateien, die von Java Image IO unterstützt werden - JPG, BMP, JPEG, WBMP, PNG und GIF.

4. Miniaturbild

Thumbnailator ist eine Open-Source-Bibliothek zur Größenänderung von Bildern für Java, die eine progressive bilineare Skalierung verwendet. Es unterstützt JPG, BMP, JPEG, WBMP, PNG und 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

Bei der Definition der Breite und Höhe des Zielbilds sollten wir auch das Bildseitenverhältnis berücksichtigen. Auf diese Weise behält das Bild seine ursprünglichen Proportionen bei und wird nicht gedehnt.

7. Fazit

In diesem Artikel wurden einige Möglichkeiten zum Ändern der Bildgröße in Java erläutert. Wir haben auch erfahren, wie viele verschiedene Faktoren den Größenänderungsprozess beeinflussen können.

Komplette Codebeispiele sind auf GitHub verfügbar.