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

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

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

ابدأ الدورة

العمل مع الصور باستخدام TypeScript: تغيير الحجم (resize) والقص (crop)

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



1. Canvas API: معالجة من جانب العميل بدون تبعيات

يعتبر HTMLCanvasElement في المتصفح أسهل طريقة للتعامل مع الصور. لا يتطلب تثبيت حزم إضافية ويعمل في أي متصفح حديث.



1.1. تغيير الحجم (resize) عبر Canvas

الفكرة الأساسية هي رسم الصورة الأصلية على canvas بأبعاد جديدة، ثم تصدير النتيجة.

function resizeImage(  source: HTMLImageElement,  targetWidth: number,  targetHeight: number): Promise<Blob> {  return new Promise((resolve, reject) => {    const canvas = document.createElement('canvas');    canvas.width = targetWidth;    canvas.height = targetHeight;    const ctx = canvas.getContext('2d');    if (!ctx) {      reject(new Error('Canvas context not supported'));      return;    }    // رسم الصورة بالأبعاد الجديدة    ctx.drawImage(source, 0, 0, targetWidth, targetHeight);    // التصدير إلى Blob (التنسيق الافتراضي هو PNG)    canvas.toBlob((blob) => {      if (blob) resolve(blob);      else reject(new Error('Failed to create blob'));    }, 'image/jpeg', 0.9); // يمكن تحديد التنسيق والجودة  });}

هام: عند تكبير الصورة (upscale)، قد تتدهور الجودة - يستخدم canvas الاستيفاء الثنائي الخطي. هذا مقبول للمعاينات، لكنه غير مناسب للطباعة.



1.2. القص (crop) بالإحداثيات

يتطلب القص تحديد منطقة مستطيلة من الصورة الأصلية.

function cropImage(  source: HTMLImageElement,  x: number,  y: number,  width: number,  height: number): Promise<Blob> {  return new Promise((resolve, reject) => {    const canvas = document.createElement('canvas');    canvas.width = width;    canvas.height = height;    const ctx = canvas.getContext('2d');    if (!ctx) {      reject(new Error('Canvas not supported'));      return;    }    // قص جزء من الصورة الأصلية    ctx.drawImage(source, x, y, width, height, 0, 0, width, height);    canvas.toBlob((blob) => {      if (blob) resolve(blob);      else reject(new Error('Blob creation failed'));    }, 'image/png');  });}

نصيحة: تأكد دائمًا من أن الإحداثيات x, y, width, height لا تتجاوز حدود الصورة الأصلية، وإلا سيعيد canvas مناطق فارغة.



2. المعالجة من جانب الخادم: sharp و jimp

إذا كنت تعمل في بيئة Node.js و TypeScript، فإن مكتبات sharp (C++ native، أداء عالي) و jimp (JS خالص، عبر المنصات) هي الحلول القياسية.



2.1. التثبيت والاستيراد

// التثبيت// npm install sharp// npm install jimp

import sharp from 'sharp';import Jimp from 'jimp';


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

async function resizeWithSharp(  inputPath: string,  outputPath: string,  width: number,  height: number): Promise<void> {  await sharp(inputPath)    .resize(width, height, {      fit: 'cover',      // 'cover' - يقص الزائد، 'contain' - يضمن الاحتواء      position: 'center' // نقطة المرجع عند القص    })    .toFile(outputPath);}

تحدد المعلمة fit استراتيجية الاحتواء:

  • cover —

توصيات