العمل مع الصور في Java: تغيير الحجم والقص (resize, crop)
\n\nفي تطوير تطبيقات الويب وتطبيقات سطح المكتب الحديثة، غالبًا ما تنشأ الحاجة إلى معالجة ملفات الرسوميات. توفر Java مجموعة أدوات مدمجة قوية للعمل مع الصور، دون الحاجة إلى تثبيت مكتبات خارجية. في هذه المقالة، سنشرح بالتفصيل عمليتين أساسيتين: تغيير الحجم (resize) وقص (crop) الصور باستخدام الفئات القياسية javax.imageio و java.awt.
الفئات الرئيسية في Java لمعالجة الصور
\n\nقبل الانتقال إلى الأمثلة، دعنا نتعرف على المكونات الأساسية لـ Java 2D API التي سنحتاجها للعمل:
\n\n- \n
BufferedImage— الفئة الرئيسية لتمثيل الصورة مع إمكانية الوصول إلى البكسلات. \n Graphics2D— سياق الرسم، الذي يسمح بإجراء التحويلات والقياس والرسم. \n AffineTransform— فئة للتحويلات الأفينية (القياس، التدوير، الإزاحة). \n ImageIO— فئة مساعدة لقراءة وكتابة الصور بتنسيقات مختلفة (JPEG, PNG, BMP وغيرها). \n
جميع هذه الفئات مضمنة في التوزيعة القياسية لـ JDK، لذلك لا يتطلب استخدامها إضافة تبعيات إضافية (Maven/Gradle).
\n\n1. تغيير حجم الصورة (resize)
\n\nيمكن تنفيذ عملية تغيير الحجم (القياس) بطريقتين رئيسيتين: باستخدام Graphics2D (الطريقة الأكثر مرونة) أو عبر AffineTransformOp (للتحكم الأكثر دقة في الاستيفاء). سننظر في كلا الأسلوبين.
الطريقة 1: عبر Graphics2D (موصى بها لمعظم المهام)
\n\nهذه الطريقة مناسبة عندما تحتاج إلى تغيير الحجم بسرعة مع الحفاظ على الجودة. نقوم برسم الصورة الأصلية على لوحة BufferedImage جديدة بالحجم المطلوب.
import java.awt.*;\nimport java.awt.image.BufferedImage;\nimport java.io.File;\nimport javax.imageio.ImageIO;\n\npublic class ImageResizer {\n\n public static BufferedImage resize(BufferedImage originalImage, int targetWidth, int targetHeight) {\n // إنشاء صورة جديدة بالأبعاد المحددة ونوع RGB\n BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);\n \n // الحصول على سياق الرسم\n Graphics2D graphics2D = resizedImage.createGraphics();\n \n // تفعيل التنعيم للحصول على نتيجة أفضل جودة\n graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);\n graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);\n graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\n \n // رسم الصورة الأصلية مع تغيير حجمها لتناسب الأبعاد الجديدة\n graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);\n graphics2D.dispose(); // تحرير الموارد\n \n return resizedImage;\n }\n\n public static void main(String[] args) throws Exception {\n // قراءة الصورة الأصلية\n BufferedImage original = ImageIO.read(new File("input.jpg"));\n \n // تغيير الحجم إلى 800x600 بكسل\n BufferedImage resized = resize(original, 800, 600);\n \n // حفظ النتيجة\n ImageIO.write(resized, "jpg", new File("output_resized.jpg"));\n System.out.println("تم تغيير حجم الصورة وحفظها.");\n }\n}\n\nهام: استخدم RenderingHints لتحسين الجودة. VALUE_INTERPOLATION_BILINEAR يعطي توازنًا جيدًا بين السرعة والجودة، بينما VALUE_INTERPOLATION_BICUBIC يعطي أقصى