Skip to content

الأمثلة

توفر هذه الصفحة أمثلة استخدام متنوعة لـ Sharp، من العمليات الأساسية إلى التقنيات المتقدمة.

الأمثلة الأساسية

تغيير حجم الصور

javascript
import sharp from 'sharp';

// تغيير إلى حجم ثابت
await sharp('input.jpg')
  .resize(300, 200)
  .toFile('resized.jpg');

// الحفاظ على نسبة العرض إلى الارتفاع
await sharp('input.jpg')
  .resize(300, null)
  .toFile('resized.jpg');

// استخدام أوضاع التكيف المختلفة
await sharp('input.jpg')
  .resize(300, 200, {
    fit: 'cover',        // القص للتكيف
    position: 'center'   // القص المركزي
  })
  .toFile('cover.jpg');

تحويل التنسيق

javascript
// JPEG إلى PNG
await sharp('input.jpg')
  .png()
  .toFile('output.png');

// PNG إلى WebP
await sharp('input.png')
  .webp({ quality: 80 })
  .toFile('output.webp');

// التحويل إلى AVIF
await sharp('input.jpg')
  .avif({ quality: 80 })
  .toFile('output.avif');

إنشاء صور مصغرة

javascript
// إنشاء صورة مصغرة مربعة
await sharp('input.jpg')
  .resize(150, 150, { fit: 'cover' })
  .jpeg({ quality: 90 })
  .toFile('thumbnail.jpg');

// إنشاء صور مصغرة بأحجام مختلفة
const sizes = [150, 300, 600];
const promises = sizes.map(size => 
  sharp('input.jpg')
    .resize(size, size, { fit: 'cover' })
    .jpeg({ quality: 85 })
    .toFile(`thumbnail-${size}.jpg`)
);

await Promise.all(promises);

الأمثلة المتقدمة

تركيب الصور

javascript
// إضافة علامة مائية على الصورة
await sharp('input.jpg')
  .composite([{
    input: 'watermark.png',
    top: 10,
    left: 10
  }])
  .jpeg()
  .toFile('with-watermark.jpg');

// إنشاء شبكة صور
const grid = await sharp({
  create: {
    width: 600,
    height: 400,
    channels: 4,
    background: { r: 255, g: 255, b: 255, alpha: 1 }
  }
})
.composite([
  { input: 'image1.jpg', top: 0, left: 0 },
  { input: 'image2.jpg', top: 0, left: 300 },
  { input: 'image3.jpg', top: 200, left: 0 },
  { input: 'image4.jpg', top: 200, left: 300 }
])
.jpeg()
.toFile('grid.jpg');

تأثيرات الفلتر

javascript
// تطبيق فلاتر متعددة
await sharp('input.jpg')
  .blur(3)           // الضبابية
  .sharpen()         // الحدّة
  .modulate({        // تعديل الألوان
    brightness: 1.1,
    saturation: 0.8
  })
  .jpeg({ quality: 85 })
  .toFile('filtered.jpg');

// إنشاء تأثير قديم
await sharp('input.jpg')
  .modulate({
    brightness: 0.9,
    saturation: 0.7,
    hue: 30
  })
  .tint({ r: 255, g: 200, b: 150 })
  .jpeg({ quality: 80 })
  .toFile('vintage.jpg');

المعالجة المجمعة

javascript
import fs from 'fs';
import path from 'path';

async function processDirectory(inputDir, outputDir) {
  const files = fs.readdirSync(inputDir);
  const imageFiles = files.filter(file => 
    /\.(jpg|jpeg|png|webp)$/i.test(file)
  );

  const promises = imageFiles.map(async file => {
    const inputPath = path.join(inputDir, file);
    const outputPath = path.join(outputDir, `processed-${file}`);

    await sharp(inputPath)
      .resize(800, 600, { fit: 'inside' })
      .jpeg({ quality: 80 })
      .toFile(outputPath);

    console.log(`اكتملت المعالجة: ${file}`);
  });

  await Promise.all(promises);
  console.log('اكتملت معالجة جميع الملفات!');
}

processDirectory('./input', './output');

الصور المتجاوبة

javascript
// إنشاء صور متجاوبة
const sizes = [
  { width: 320, suffix: 'sm' },
  { width: 640, suffix: 'md' },
  { width: 1024, suffix: 'lg' },
  { width: 1920, suffix: 'xl' }
];

const formats = ['jpeg', 'webp', 'avif'];

async function generateResponsiveImages(inputFile) {
  const promises = [];

  for (const size of sizes) {
    for (const format of formats) {
      const outputFile = `output-${size.suffix}.${format}`;
      
      let pipeline = sharp(inputFile)
        .resize(size.width, null, { fit: 'inside' });

      switch (format) {
        case 'jpeg':
          pipeline = pipeline.jpeg({ quality: 80 });
          break;
        case 'webp':
          pipeline = pipeline.webp({ quality: 80 });
          break;
        case 'avif':
          pipeline = pipeline.avif({ quality: 80 });
          break;
      }

      promises.push(pipeline.toFile(outputFile));
    }
  }

  await Promise.all(promises);
  console.log('اكتمل إنشاء الصور المتجاوبة!');
}

generateResponsiveImages('input.jpg');

أمثلة تحسين الأداء

المعالجة المتدفقة

javascript
import fs from 'fs';

// معالجة الملفات الكبيرة
const pipeline = sharp()
  .resize(800, 600)
  .jpeg({ quality: 80 });

fs.createReadStream('large-input.jpg')
  .pipe(pipeline)
  .pipe(fs.createWriteStream('output.jpg'));

// معالجة ملفات متعددة
const processFile = (inputFile, outputFile) => {
  return new Promise((resolve, reject) => {
    sharp(inputFile)
      .resize(300, 200)
      .jpeg({ quality: 80 })
      .pipe(fs.createWriteStream(outputFile))
      .on('finish', resolve)
      .on('error', reject);
  });
};

const files = ['file1.jpg', 'file2.jpg', 'file3.jpg'];
const promises = files.map((file, index) => 
  processFile(file, `output-${index}.jpg`)
);

await Promise.all(promises);

تحسين الذاكرة

javascript
// استخدام Buffer لمعالجة الملفات الصغيرة
const buffer = await sharp('input.jpg')
  .resize(300, 200)
  .jpeg({ quality: 80 })
  .toBuffer();

// استخدام التدفق لمعالجة الملفات الكبيرة
const stream = sharp('large-input.jpg')
  .resize(800, 600)
  .jpeg({ quality: 80 });

// المعالجة المجزأة
const chunkSize = 1024 * 1024; // 1MB
const chunks = [];

stream.on('data', chunk => {
  chunks.push(chunk);
});

stream.on('end', () => {
  const buffer = Buffer.concat(chunks);
  fs.writeFileSync('output.jpg', buffer);
});

التحكم في التزامن

javascript
// تحديد عدد التزامن
async function processWithConcurrency(files, concurrency = 3) {
  const results = [];
  
  for (let i = 0; i < files.length; i += concurrency) {
    const batch = files.slice(i, i + concurrency);
    const batchPromises = batch.map(file => 
      sharp(file)
        .resize(300, 200)
        .jpeg({ quality: 80 })
        .toFile(`processed-${file}`)
    );
    
    const batchResults = await Promise.all(batchPromises);
    results.push(...batchResults);
  }
  
  return results;
}

const files = ['file1.jpg', 'file2.jpg', 'file3.jpg', 'file4.jpg'];
await processWithConcurrency(files, 2);

أمثلة الأدوات المساعدة

استخراج معلومات الصورة

javascript
async function getImageInfo(file) {
  const metadata = await sharp(file).metadata();
  const stats = await sharp(file).stats();
  
  return {
    filename: file,
    format: metadata.format,
    width: metadata.width,
    height: metadata.height,
    size: metadata.size,
    channels: metadata.channels,
    isOpaque: stats.isOpaque,
    dominantColor: stats.dominant
  };
}

const info = await getImageInfo('input.jpg');
console.log('معلومات الصورة:', info);

مقارنة الصور

javascript
async function compareImages(file1, file2) {
  const [stats1, stats2] = await Promise.all([
    sharp(file1).stats(),
    sharp(file2).stats()
  ]);
  
  return {
    file1: stats1,
    file2: stats2,
    dominantDiff: {
      r: Math.abs(stats1.dominant.r - stats2.dominant.r),
      g: Math.abs(stats1.dominant.g - stats2.dominant.g),
      b: Math.abs(stats1.dominant.b - stats2.dominant.b)
    }
  };
}

const comparison = await compareImages('image1.jpg', 'image2.jpg');
console.log('نتائج مقارنة الصور:', comparison);

التحقق من الصور

javascript
async function validateImage(file) {
  try {
    const metadata = await sharp(file).metadata();
    
    const validation = {
      isValid: true,
      format: metadata.format,
      width: metadata.width,
      height: metadata.height,
      size: metadata.size,
      errors: []
    };
    
    // التحقق من الأبعاد
    if (metadata.width > 5000 || metadata.height > 5000) {
      validation.errors.push('أبعاد الصورة كبيرة جدًا');
    }
    
    // التحقق من حجم الملف
    if (metadata.size > 10 * 1024 * 1024) { // 10MB
      validation.errors.push('حجم الملف كبير جدًا');
    }
    
    // التحقق من التنسيق
    const allowedFormats = ['jpeg', 'png', 'webp'];
    if (!allowedFormats.includes(metadata.format)) {
      validation.errors.push('تنسيق غير مدعوم');
    }
    
    if (validation.errors.length > 0) {
      validation.isValid = false;
    }
    
    return validation;
  } catch (error) {
    return {
      isValid: false,
      errors: [error.message]
    };
  }
}

const validation = await validateImage('input.jpg');
console.log('نتائج التحقق:', validation);

مثال تطبيق كامل

javascript
import sharp from 'sharp';
import fs from 'fs';
import path from 'path';

class ImageProcessor {
  constructor(options = {}) {
    this.options = {
      quality: 80,
      maxWidth: 1920,
      maxHeight: 1080,
      ...options
    };
  }

  async processImage(inputPath, outputPath, options = {}) {
    try {
      const metadata = await sharp(inputPath).metadata();
      
      // حساب أبعاد التغيير
      const { width, height } = this.calculateDimensions(
        metadata.width,
        metadata.height,
        options
      );
      
      // معالجة الصورة
      await sharp(inputPath)
        .resize(width, height, { fit: 'inside' })
        .jpeg({ quality: this.options.quality })
        .toFile(outputPath);
      
      return {
        success: true,
        originalSize: { width: metadata.width, height: metadata.height },
        newSize: { width, height },
        outputPath
      };
    } catch (error) {
      return {
        success: false,
        error: error.message
      };
    }
  }

  calculateDimensions(originalWidth, originalHeight, options = {}) {
    const { maxWidth = this.options.maxWidth, maxHeight = this.options.maxHeight } = options;
    
    let width = originalWidth;
    let height = originalHeight;
    
    if (width > maxWidth) {
      height = (height * maxWidth) / width;
      width = maxWidth;
    }
    
    if (height > maxHeight) {
      width = (width * maxHeight) / height;
      height = maxHeight;
    }
    
    return { width: Math.round(width), height: Math.round(height) };
  }

  async batchProcess(inputDir, outputDir) {
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }

    const files = fs.readdirSync(inputDir);
    const imageFiles = files.filter(file => 
      /\.(jpg|jpeg|png|webp)$/i.test(file)
    );

    const results = [];
    
    for (const file of imageFiles) {
      const inputPath = path.join(inputDir, file);
      const outputPath = path.join(outputDir, `processed-${file}`);
      
      const result = await this.processImage(inputPath, outputPath);
      results.push({ file, ...result });
    }
    
    return results;
  }
}

// مثال الاستخدام
const processor = new ImageProcessor({ quality: 85 });

// معالجة ملف واحد
const result = await processor.processImage('input.jpg', 'output.jpg');

// المعالجة المجمعة
const results = await processor.batchProcess('./input', './output');

console.log('نتائج المعالجة:', results);

الخطوات التالية

تم الإصدار بموجب رخصة Apache 2.0.