العمل مع الصور في Node.js: تغيير الحجم والقص
في تطوير الويب الحديث، غالبًا ما تكون هناك حاجة لمعالجة الصور من جانب الخادم: تغيير الحجم، القص، تحويل التنسيقات. يقدم Node.js عدة مكتبات قوية لهذه المهام. في هذه المقالة، سنتناول أشهر مكتبتين — Sharp (أداء عالٍ، مبني على libvips) وJimp (JavaScript خالص، لا يتطلب تبعيات أصلية).
1. التثبيت والتحضير
للبدء، أنشئ مشروعًا جديدًا وقم بتثبيت إحدى المكتبات:
mkdir image-processor && cd image-processornpm init -ynpm install sharp jimp2. تغيير الحجم (resize) باستخدام Sharp
Sharp هي مكتبة سريعة مكتوبة بلغة C، وهي مثالية للإنتاج. تدعم المعالجة التدفقية والتحديد التلقائي للتنسيق.
const sharp = require('sharp');
// تغيير حجم بسيط إلى عرض 300 بكسل (يحافظ الارتفاع على النسب)sharp('input.jpg') .resize(300) .toFile('output-300.jpg') .then(() => console.log('تم!' )) .catch(err => console.error(err));
// تغيير حجم إجباري إلى أبعاد دقيقة 200x200 (مع تشويه)sharp('input.jpg') .resize(200, 200, { fit: 'fill' }) .toFile('output-fill.jpg');
// تغيير حجم ذكي مع الحفاظ على النسب (قص من المنتصف)sharp('input.jpg') .resize(200, 200, { fit: 'cover', position: 'centre' }) .toFile('output-cover.jpg');3. القص (crop) باستخدام Sharp
تتيح طريقة extract قص منطقة مستطيلة من الصورة.
const sharp = require('sharp');
// قص المنطقة: left=100, top=50, width=400, height=300sharp('input.jpg') .extract({ left: 100, top: 50, width: 400, height: 300 }) .toFile('cropped.jpg') .then(info => console.log('تم القص:', info));4. العمل مع Jimp (JavaScript خالص)
يعمل Jimp بشكل أبطأ من Sharp، لكنه لا يتطلب تجميع وحدات أصلية — مثالي للمهام البسيطة أو البيئات التي لا تملك صلاحيات تثبيت حزم النظام.
const Jimp = require('jimp');
// تغيير الحجم إلى عرض 300 بكسلJimp.read('input.jpg') .then(image => { return image .resize(300, Jimp.AUTO) // AUTO يحافظ على النسب .writeAsync('output-jimp.jpg'); }) .then(() => console.log('تم تغيير الحجم باستخدام Jimp')) .catch(err => console.error(err));
// القص (crop) مع الإحداثياتJimp.read('input.jpg') .then(image => { return image .crop(100, 50, 400, 300) // x, y, width, height .writeAsync('cropped-jimp.jpg'); }) .catch(err => console.error(err));5. مثال مدمج: تغيير الحجم + القص في خطوة واحدة
غالبًا ما يكون مطلوبًا القص أولاً ثم التصغير. يقوم Sharp بذلك بكفاءة بفضل خط أنابيبه الداخلي:
const sharp = require('sharp');
sharp('input.jpg') .extract({ left: 50, top: 30, width: 800, height: 600 }) .resize(400, 300, { fit: 'cover' }) .toFile('result.jpg') .then(info => console.log('الحجم النهائي:', info.width, 'x', info.height));6. مقارنة Sharp vs Jimp
- الأداء: Sharp أسرع بمقدار 5-10 مرات للملفات الكبيرة.
- التثبيت: Jimp لا يتطلب تبعيات أصلية (فقط npm install).
- الوظائف: Sharp يدعم المزيد من التنسيقات (heif, tiff, avif) والمرشحات المتقدمة.
- المعالجة التدفقية: Sharp يعمل مع تدفقات Node.js (pipe)، بينما Jimp يعمل فقط مع المخازن المؤقتة.
- التوصية: للخدمات عالية التحميل، اختر Sharp. للنصوص البسيطة أو المشاريع التعليمية، استخدم Jimp.
7. العمل مع المخزن المؤقت (بدون حفظ في ملف)
غالبًا ما تأتي الصور عبر HTTP أو تُخزن في الذاكرة. تدعم كلتا المكتبتين العمل مع Buffer:
const sharp = requ