العمل مع الصور في Node.js: تغيير الحجم والقص باستخدام Sharp
\n\nفي تطوير الويب الحديث، تعد معالجة الصور على جانب الخادم مهمة شائعة. يقدم Node.js عدة مكتبات قوية للعمل مع الرسومات. في هذه المقالة، سنستعرض بالتفصيل مكتبة Sharp - وهي أداة سريعة وفعالة لتغيير حجم الصور (resize) وقصها (crop).
\n\nلماذا Sharp؟
\n\nتستخدم Sharp مكتبات libvips الأصلية، مما يجعلها واحدة من أكثر الحلول أداءً لـ Node.js. المزايا الرئيسية:
\n- \n
- سرعة معالجة عالية (أسرع بعدة مرات من البدائل في JavaScript الخالص) \n
- استهلاك منخفض للذاكرة \n
- دعم جميع التنسيقات الشائعة: JPEG، PNG، WebP، AVIF، TIFF
- واجهة برمجة تطبيقات بسيطة وواضحة
- إمكانية العمل مع التدفقات (streams)
التثبيت
\n\nيتم تثبيت Sharp في مشروع Node.js بأمر واحد:
\n\nnpm install sharp\n\nبعد التثبيت، المكتبة جاهزة للاستخدام. تأكد من تثبيت التبعيات اللازمة لبناء الوحدة الأصلية في النظام (عادةً ما يحدث هذا تلقائيًا).
\n\nتغيير الحجم الأساسي (resize)
\n\nتتيح طريقة resize() تغيير أبعاد الصورة. دعنا نستعرض حالات الاستخدام الأساسية.
مثال 1: تغيير الحجم البسيط
\n\nconst sharp = require('sharp');\nconst path = require('path');\n\nasync function resizeImage() {\n try {\n await sharp('input.jpg')\n .resize(300, 200) // العرض 300px، الارتفاع 200px\n .toFile('output.jpg');\n console.log('تم تغيير حجم الصورة بنجاح');\n } catch (error) {\n console.error('خطأ:', error);\n }\n}\n\nresizeImage();\n\nفي هذا المثال، سيتم ضغط الصورة إلى أبعاد دقيقة 300x200 بكسل، مما قد يشوه النسب.
\n\nمثال 2: الحفاظ على النسب
\n\nasync function resizeWithProportions() {\n await sharp('input.jpg')\n .resize({\n width: 400, // العرض فقط\n height: undefined, // سيتم حساب الارتفاع تلقائيًا\n fit: 'inside' // الحفاظ على النسب\n })\n .toFile('output_inside.jpg');\n \n console.log('تم الحفاظ على النسب');\n}\n\nيقبل المعامل fit عدة قيم:
- \n
cover- يقص الصورة لملء الأبعاد المحددة بالكامل (الافتراضي) \n contain- يدرج الصورة داخل الأبعاد المحددة مع الحفاظ على النسب \n fill- يمتد الصورة إلى الأبعاد المحددة \n inside- يقلل الصورة لتناسب الأبعاد المحددة \n outside- يكبر الصورة لتتجاوز الأبعاد المحددة \n
قص الصور (crop)
\n\nتوفر Sharp طريقتين رئيسيتين للقص: باستخدام طريقة extract() ومن خلال معاملات resize().
طريقة extract()
\n\nتسمح بقص منطقة مستطيلة من الصورة بناءً على إحداثيات محددة:
\n\nasync function cropImage() {\n await sharp('input.jpg')\n .extract({\n left: 100, // الهامش من اليسار\n top: 50, // الهامش من الأعلى\n width: 300, // عرض المنطقة\n height: 200 // ارتفاع المنطقة\n })\n .toFile('cropped.jpg');\n \n console.log('تم تنفيذ القص');\n}\n\nالقص التلقائي أثناء تغيير الحجم
\n\nغالبًا ما يكون مطلوبًا تغيير الحجم وقص الصورة في نفس الوقت. يتم ذلك باستخدام المعامل gravity أو position:
async function cropAndResize() {\n await sharp('input.jpg')\n .resize(200, 200, {\n fit: 'cover', // قص إلى الأبعاد المحددة تمامًا