HOWTO · Java

Bild zuschneiden in Java

In diesem Artikel wird erläutert, wie Sie ein Bild in Java zuschneiden, und dafür verwenden wir die subimage-Funktion aus der BufferedImage-Klasse, um ein Bild in Java zuzuschneiden.

Auf dieser Seite

Schneiden Sie mit BufferedImage.getSubimage(x, y, width, height) einen rechteckigen Bereich eines Bildes in Java aus und schreiben Sie das zurückgegebene Bild anschließend mit ImageIO. Das Rechteck beginnt an seiner oberen linken Ecke (x, y); Breite und Höhe bestimmen, welcher Teil des Ausgangsbildes erhalten bleibt.

Ein Bild mit BufferedImage.getSubimage zuschneiden

BufferedImage steht für ein Bild, dessen Pixel im Arbeitsspeicher zugänglich sind. Die Methode getSubimage gibt eine Ansicht eines rechteckigen Bereichs dieses Bildes zurück. Die Argumente sind x und y, also die Koordinaten der oberen linken Ecke des Rechtecks, gefolgt von width und height. Das zurückgegebene Bild hat die angeforderten Abmessungen und verwendet dieselben Pixeldaten wie das Ausgangsbild. Verwenden Sie daher eine Kopie, wenn spätere Änderungen an einem der Bilder unabhängig voneinander bleiben sollen.

Ein Bild einlesen und das zugeschnittene Ergebnis speichern

Übergeben Sie dem Programm als Argumente den Pfad zu einem Eingabebild und einen Ausgabepfad mit der Endung .png. Ohne Argumente erstellt das Beispiel in einem temporären Verzeichnis ein kleines PNG-Beispielbild. So lässt sich der gesamte Ablauf auch ohne zusätzliche Bilddatei nachvollziehen. Das Programm liest das ausgewählte Eingabebild mit ImageIO ein, schneidet den Rechteckbereich aus und speichert ihn als PNG. Passen Sie die Koordinaten des Ausschnitts an Ihr Bild an.

Führen Sie dieses eigenständige Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.imageio.ImageIO;

public class Main {
    public static void main(String[] args) {
        try {
            Path inputPath;
            Path outputPath;
            if (args.length == 2) {
                inputPath = Paths.get(args[0]);
                outputPath = Paths.get(args[1]);
            } else if (args.length == 0) {
                Path folder = Files.createTempDirectory("java-crop-");
                inputPath = folder.resolve("source.png");
                outputPath = folder.resolve("crop.png");

                BufferedImage sample = new BufferedImage(100, 80, BufferedImage.TYPE_INT_RGB);
                for (int y = 0; y < sample.getHeight(); y++) {
                    for (int x = 0; x < sample.getWidth(); x++) {
                        sample.setRGB(x, y, (x < 50) ? Color.BLUE.getRGB() : Color.ORANGE.getRGB());
                    }
                }
                ImageIO.write(sample, "png", inputPath.toFile());
            } else {
                System.out.println("Provide both an input path and an output path.");
                return;
            }

            if (!outputPath.getFileName().toString().toLowerCase().endsWith(".png")) {
                System.out.println("The output path must end in .png.");
                return;
            }

            BufferedImage source = ImageIO.read(inputPath.toFile());
            if (source == null) {
                System.out.println("The input format is not supported.");
                return;
            }

            int x = 20;
            int y = 15;
            int width = 40;
            int height = 30;
            if (x < 0 || y < 0 || width <= 0 || height <= 0
                    || x > source.getWidth() - width || y > source.getHeight() - height) {
                System.out.println("The crop rectangle must fit inside the input image.");
                return;
            }

            BufferedImage crop = source.getSubimage(x, y, width, height);
            boolean written = ImageIO.write(crop, "png", outputPath.toFile());
            if (written) {
                System.out.println("Saved crop: " + crop.getWidth() + "x" + crop.getHeight());
            } else {
                System.out.println("No PNG writer is available.");
            }
        } catch (IOException ex) {
            System.out.println("Image file operation failed: " + ex.getMessage());
        }
    }
}
Saved crop: 40x30

Das ausgewählte Ausgangsbild ist neben dem zugeschnittenen Ergebnis zu sehen. Die bereitgestellten Bilder veranschaulichen den sichtbaren Effekt des Zuschneidens eines echten Bildes.

Vorher Nachher
Originalbild vor dem Zuschneiden Zugeschnittenes Bild mit dem ausgewählten Bereich

Koordinaten und Abmessungen des Ausschnitts festlegen

Die Koordinaten beginnen in der oberen linken Ecke des Ausgangsbildes: x wächst nach rechts, y nach unten. Im Beispiel ist (20, 15) der Startpunkt des Ausschnitts; seine Größe beträgt 40 mal 30. Für ein Bild mit der Breite W und der Höhe H müssen x und y nichtnegativ sowie Breite und Höhe positiv sein. Außerdem muss gelten: x + width <= W und y + height <= H. Ein Ausschnitt, der beispielsweise bei x = 20 beginnt und 40 Pixel breit ist, endet in Spalte 59. Das Ausgangsbild muss daher mindestens 60 Pixel breit sein.

Ungültige Eingaben und häufige Fehler behandeln

ImageIO.read(File) kann eine IOException auslösen, wenn eine Datei nicht gelesen werden kann. Die Methode kann außerdem null zurückgeben, wenn kein registrierter Reader das Eingabeformat erkennt. Prüfen Sie daher den Rückgabewert, bevor Sie getSubimage aufrufen. Das Beispiel fängt Fehler bei Dateioperationen ab und prüft, ob ein PNG-Writer verfügbar ist. ImageIO.write(RenderedImage, String, File) gibt false zurück, wenn das angeforderte Format nicht geschrieben werden kann.

Ein Ausschnitt, der außerhalb des Ausgangsbildes liegt oder eine nichtpositive Breite oder Höhe hat, führt dazu, dass getSubimage eine RasterFormatException auslöst. Weitere Informationen finden Sie in der API-Dokumentation zu BufferedImage.getSubimage. Prüfen Sie die Abmessungen vor dem Aufruf, besonders wenn die Koordinaten aus Benutzereingaben stammen. Geben Sie für das Beispiel einen beschreibbaren Ausgabeort an und achten Sie darauf, dass der PNG-Formatname zur Dateiendung .png passt.