العمل مع الصور في TypeScript: تغيير الحجم والقص باستخدام Sharp وJimp

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

العمل مع الصور في TypeScript: تغيير الحجم والقص

\n

في تطوير الويب الحديث، تعد معالجة الصور واحدة من أكثر المهام طلبًا. TypeScript، بفضل الكتابة الصارمة والتكامل مع Node.js، يتيح إنشاء أدوات موثوقة وعالية الأداء لتغيير حجم (resize) وقص (crop) الصور. في هذه المقالة، سنستعرض مكتبتين شائعتين: Sharp (معالجة من جانب الخادم) وJimp (JavaScript خالص)، بالإضافة إلى النهج الأصلي باستخدام Canvas API للمتصفح.

\n\n

1. تثبيت وإعداد مشروع TypeScript

\n

للبدء، أنشئ مشروعًا وقم بتثبيت التبعيات اللازمة:

\n
npm init -y\nnpm install typescript @types/node sharp jimp\nnpx tsc --init
\n

في ملف tsconfig.json، تأكد من أن "module": "commonjs" و "target": "ES2020".

\n\n

2. مكتبة Sharp — معالجة سريعة من جانب الخادم

\n

تستخدم Sharp الوحدة النمطية الأصلية libvips وتوفر أداءً عاليًا. مناسبة لتطبيقات الخادم (NestJS، Express).

\n\n

2.1. تغيير الحجم (resize) باستخدام Sharp

\n

تأخذ طريقة resize() العرض والارتفاع. يمكن تحديد معامل واحد فقط وسيتم حساب الثاني بشكل نسبي.

\n
import sharp from 'sharp';\n\nasync function resizeImage(inputPath: string, outputPath: string, width: number, height?: number): Promise<void> {\n  try {\n    await sharp(inputPath)\n      .resize(width, height, {\n        fit: 'cover',       // 'cover', 'contain', 'fill', 'inside', 'outside'\n        position: 'center'  // موضع القص عند استخدام cover\n      })\n      .toFile(outputPath);\n    console.log(`تم تغيير حجم الصورة: ${outputPath}`);\n  } catch (error) {\n    console.error('خطأ في تغيير الحجم:', error);\n  }\n}\n\n// مثال على الاستخدام\nresizeImage('input.jpg', 'output_800x600.jpg', 800, 600);
\n\n

2.2. القص (crop) باستخدام Sharp

\n

تتيح طريقة extract() قص منطقة مستطيلة. المعاملات: left، top، width، height.

\n
async function cropImage(\n  inputPath: string,\n  outputPath: string,\n  left: number,\n  top: number,\n  cropWidth: number,\n  cropHeight: number\n): Promise<void> {\n  try {\n    await sharp(inputPath)\n      .extract({ left, top, width: cropWidth, height: cropHeight })\n      .toFile(outputPath);\n    console.log(`تم القص: ${outputPath}`);\n  } catch (error) {\n    console.error('خطأ في القص:', error);\n  }\n}\n\n// مثال: قص المنتصف 400x400 من صورة 800x600\ncropImage('input.jpg', 'cropped_center.jpg', 200, 100, 400, 400);
\n\n

2.3. الجمع بين تغيير الحجم والقص

\n

يتيح Sharp دمج العمليات في سلسلة. على سبيل المثال، التصغير أولاً ثم القص:

\n
async function resizeAndCrop(inputPath: string, outputPath: string): Promise<void> {\n  await sharp(inputPath)\n    .resize(500, 500, { fit: 'inside' })  // تصغير إلى 500x500 بدون قص\n    .extract({ left: 50, top: 50, width: 400, height: 400 }) // قص المنتصف\n    .toFile(outputPath);\n}\n\nresizeAndCrop('input.jpg', 'processed.jpg');
\n\n

3. مكتبة Jimp — JavaScript خالص بدون تبعيات أصلية

\n

تعمل Jimp على JavaScript خالص، ولا تتطلب تثبيت مكتبات نظام إضافية. مثالية للبيئات المعزولة (مثل AWS Lambda).

\n\n

3.1. تثبيت Jimp

\n
npm install jimp\nnpm install @types/jimp  // لـ TypeScript
\n\n

3.2. تغيير الحجم باستخدام Jimp

\n
import Jimp from 'jimp';\n\nasync function resizeWithJimp(inputPath: string, outputPath: string, width: number, height: number): Promise<void> {\n  try {\n    const image = await Jimp.read(inputPath);\n    image.resize(width, height, Jimp.RESIZE_BILINEAR); // الخوارزميات: BILINEAR, BICUBIC, NEAREST_NEIGHBOR\n    awa                    

توصيات