معالجة الصور في Rust: تغيير الحجم والقص
Rust هي لغة برمجة نظامية حديثة تُستخدم بشكل متزايد في المهام التي تتطلب أداءً عالياً وموثوقية. معالجة الصور ليست استثناءً. في هذه المقالة، سننظر في عمليتين رئيسيتين - تغيير الحجم (resize) والقص (crop) - باستخدام النظام البيئي لـ Rust. المكتبات الأساسية: image (التحميل، الحفظ، التلاعبات الأساسية) و imageproc (المعالجة المتقدمة).
لماذا Rust للعمل مع الصور؟
تقدم Rust:
- عمل آمن مع الذاكرة - لا تسريبات أو سباقات بيانات.
- أداء أقصى - مشابه لـ C/C++.
- نظام بيئي غني - crate
imageيدعم JPEG، PNG، GIF، BMP، WEBP وتنسيقات أخرى. - التوازي - سهولة توسيع نطاق المعالجة على المعالجات متعددة النوى.
تثبيت التبعيات
أضف إلى Cargo.toml:
[dependencies]image = "0.25"imageproc = "0.25" # للمرشحات المتقدمة (اختياري)تحقق من الإصدارات الحالية على crates.io.
تحميل وحفظ الصورة
لنبدأ بمثال أساسي - فتح ملف وحفظ نسخة منه:
use image::{GenericImageView, ImageFormat};
fn main() -> Result<(), Box<dyn std::error::Error>> { // تحميل الصورة let img = image::open("input.jpg")?; // عرض الأبعاد println!("العرض: {}, الارتفاع: {}", img.width(), img.height()); // حفظ بتنسيق آخر img.save("output.png")?; Ok(())}طريقة image::open تحدد التنسيق تلقائياً بناءً على الامتداد أو محتوى الملف.
تغيير الحجم (resize)
تأخذ دالة resize العرض والارتفاع الجديدين، بالإضافة إلى مرشح الاستيفاء. المرشحات المتاحة: Nearest، Triangle، CatmullRom، Gaussian، Lanczos3 وغيرها.
use image::{imageops::FilterType, GenericImageView};
fn resize_image(path: &str, new_width: u32, new_height: u32) -> Result<(), Box<dyn std::error::Error>> { let img = image::open(path)?; // تغيير الحجم باستخدام مرشح Lanczos3 (جودة عالية) let resized = img.resize(new_width, new_height, FilterType::Lanczos3); // حفظ النتيجة resized.save("resized.jpg")?; println!("تم تغيير الحجم: {}x{} → {}x{}", img.width(), img.height(), new_width, new_height); Ok(())}نصيحة: للمعالجة السريعة، استخدم FilterType::Nearest (بدون استيفاء)، وللجودة القصوى استخدم Lanczos3.
تغيير الحجم بشكل متناسب
للحفاظ على نسبة العرض إلى الارتفاع، استخدم resize_to_fill (يملأ المنطقة) أو resize_to_fit (يدرج ضمن مستطيل):
use image::imageops::FilterType;
fn resize_proportional(path: &str, max_width: u32, max_height: u32) -> Result<(), Box<dyn std::error::Error>> { let img = image::open(path)?; // إدراج ضمن مستطيل (مع الحفاظ على النسب) let fitted = img.resize_to_fit(max_width, max_height, FilterType::Triangle); fitted.save("fitted.jpg")?; // ملء المنطقة (سيقص الزائد) let filled = img.resize_to_fill(max_width, max_height, FilterType::Triangle); filled.save("filled.jpg")?; Ok(())}قص الصورة (crop)
يتم القص من خلال طريقة crop، التي تأخذ إحداثيات الزاوية العلوية اليسرى (x, y) وأبعاد المنطقة:
use image::Gener