Arbeiten mit Bildern in Rust: resize und crop mit der Bibliothek image
\n\nRust ist eine moderne systemnahe Programmiersprache, die bei Aufgaben, die hohe Leistung und Sicherheit erfordern, immer beliebter wird. Eine dieser Aufgaben ist die Bildverarbeitung. In diesem Artikel werden wir im Detail betrachten, wie man mit Rust und der leistungsstarken und benutzerfreundlichen Bibliothek image die Größe von Bildern ändert (resize) und sie zuschneidet (crop). Sie erfahren, wie Sie die Bibliothek installieren, ein Bild laden, Transformationen anwenden und das Ergebnis speichern.
Installation und Einbindung der Bibliothek image
\n\nDie Bibliothek image ist der De-facto-Standard für die Arbeit mit Rastergrafiken im Rust-Ökosystem. Sie unterstützt zahlreiche Formate (PNG, JPEG, GIF, BMP, WEBP und andere) und bietet eine breite Palette an Verarbeitungsfunktionen.
Um zu beginnen, fügen Sie die Abhängigkeit in Ihre Cargo.toml-Datei ein:
[dependencies]\nimage = "0.25"\n\nDanach können Sie die benötigten Module in Ihrem Code importieren:
\n\nuse std::path::Path;\nuse image::{open, DynamicImage, GenericImageView, imageops::FilterType};\n\nBilder laden und speichern
\n\nDer erste Schritt besteht darin, ein Bild aus einer Datei zu laden. Die Bibliothek erkennt das Format automatisch anhand der Dateierweiterung. Betrachten wir ein einfaches Beispiel:
\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n // Bild laden\n let img = open("input.jpg")?;\n println!("Größe: {:?}", img.dimensions());\n // In einem anderen Format speichern\n img.save("output.png")?;\n Ok(())\n}\n\nDie Methode open() gibt ein DynamicImage zurück – eine Aufzählung, die ein Bild in einem von mehreren internen Formaten (RGB8, RGBA8, Gray8 usw.) speichern kann. Die Methode dimensions() gibt ein Tupel (u32, u32) zurück – Breite und Höhe.
Größenänderung (resize)
\n\nDie Funktion resize() akzeptiert eine neue Breite, Höhe und einen Filtertyp. Der Filter beeinflusst die Qualität des Ergebnisses und die Ausführungsgeschwindigkeit. Hier sind die wichtigsten Filter:
- \n
- Nearest – schnell, aber mit geringer Qualität (Pixelbildung). \n
- Lanczos3 – hohe Qualität, aber langsamer. \n
- CatmullRom – gute Balance zwischen Geschwindigkeit und Qualität. \n
- Gaussian – verwischt das Bild beim Verkleinern. \n
Beispiel für eine Größenänderung auf 800x600 Pixel:
\n\nuse image::imageops::FilterType;\n\nfn resize_example() -> Result<(), Box<dyn std::error::Error>> {\n let img = open("input.jpg")?;\n let resized = img.resize(800, 600, FilterType::Lanczos3);\n resized.save("resized.jpg")?;\n println!("Neue Größe: {:?}", resized.dimensions());\n Ok(())\n}\n\nWenn Sie die Proportionen beibehalten möchten, verwenden Sie resize_to_fill() (füllt den Bereich, schneidet Überflüssiges ab) oder resize_to_fit() (passt in die angegebenen Abmessungen, fügt leere Ränder hinzu). Beispiel:
// In ein 400x400 Rechteck einpassen, Proportionen beibehalten\nlet fitted = img.resize_to_fit(400, 400, FilterType::CatmullRom);\nfitted.save("fitted.jpg")?;\n\n// Ein 400x400 Rechteck füllen, Ränder abschneiden\nlet filled = img.resize_to_fill(400, 400, FilterType::Lanczos3);\nfilled.save("filled.jpg")?;\n\nBild zuschneiden (crop)
\n\nDas Zuschneiden erfolgt mit der Methode crop(), die die Koordinaten der oberen linken Ecke (x, y) sowie die Breite und Höhe des Bereichs akzeptiert. Wichtig: Die Koordinaten und Abmessungen dürfen die Grenzen des Originalbildes nicht überschreiten, da es sonst zu einer Panik kommt.
Beispiel für das Zuschneiden des mittleren Bereichs mit einer Größe von 300x200:
\n\nfn crop_example() -> Result<(), Box<dyn std::error::Error>> {\n let img = open("input.jpg")?;\n let (width, height) = img.dimensions()