Skip to content

Ví dụ nâng cao

Đây là một số ví dụ sử dụng nâng cao của Sharp, bao gồm các thao tác xử lý hình ảnh phức tạp.

Tổng hợp hình ảnh

Thêm watermark

javascript
import sharp from 'sharp';

// Thêm watermark văn bản
await sharp('input.jpg')
  .composite([
    {
      input: Buffer.from(`
        <svg width="200" height="100">
          <text x="10" y="50" font-family="Arial" font-size="24" fill="white">
            Watermark
          </text>
        </svg>
      `),
      top: 10,
      left: 10
    }
  ])
  .jpeg()
  .toFile('output.jpg');

Chồng hình ảnh

javascript
// Chồng nhiều hình ảnh
await sharp('background.jpg')
  .composite([
    {
      input: 'overlay1.png',
      top: 100,
      left: 100
    },
    {
      input: 'overlay2.png',
      top: 200,
      left: 200
    }
  ])
  .jpeg()
  .toFile('output.jpg');

Thao tác kênh

Tách kênh

javascript
// Tách kênh RGB
const channels = await sharp('input.jpg').separate();

// Lưu từng kênh
await sharp(channels[0]).toFile('red-channel.jpg');
await sharp(channels[1]).toFile('green-channel.jpg');
await sharp(channels[2]).toFile('blue-channel.jpg');

Hợp nhất kênh

javascript
// Hợp nhất từ các tệp kênh riêng biệt
await sharp('red-channel.jpg')
  .joinChannel(['green-channel.jpg', 'blue-channel.jpg'])
  .toFile('merged.jpg');

Chuyển đổi không gian màu

RGB sang CMYK

javascript
await sharp('input.jpg')
  .toColourspace(sharp.colourspace.cmyk)
  .tiff()
  .toFile('output.tiff');

Chuyển đổi sang không gian màu Lab

javascript
await sharp('input.jpg')
  .toColourspace(sharp.colourspace.lab)
  .tiff()
  .toFile('output.tiff');

Bộ lọc nâng cao

Làm sắc nét tùy chỉnh

javascript
await sharp('input.jpg')
  .sharpen({
    sigma: 1,
    flat: 1,
    jagged: 2
  })
  .toFile('output.jpg');

Hiệu chỉnh gamma

javascript
await sharp('input.jpg')
  .gamma(2.2)
  .toFile('output.jpg');

Tách sắc độ

javascript
await sharp('input.jpg')
  .tint({ r: 255, g: 0, b: 0 })
  .toFile('output.jpg');

Xử lý hình ảnh nhiều trang

Xử lý TIFF nhiều trang

javascript
// Xử lý tất cả các trang
await sharp('multi-page.tiff', { pages: -1 })
  .resize(800, 600)
  .tiff()
  .toFile('output.tiff');

// Xử lý trang cụ thể
await sharp('multi-page.tiff', { pages: 0 })
  .resize(800, 600)
  .jpeg()
  .toFile('page0.jpg');

Xử lý PDF

javascript
// Xử lý trang đầu tiên của PDF
await sharp('document.pdf', { pages: 0 })
  .resize(800, 600)
  .jpeg()
  .toFile('page0.jpg');

Tạo hình ảnh đáp ứng

Tạo nhiều kích thước

javascript
async function generateResponsiveImages(inputPath) {
  const sizes = [
    { width: 320, height: 240, suffix: 'small' },
    { width: 640, height: 480, suffix: 'medium' },
    { width: 1280, height: 960, suffix: 'large' },
    { width: 1920, height: 1440, suffix: 'xlarge' }
  ];
  
  const promises = sizes.map(async ({ width, height, suffix }) => {
    await sharp(inputPath)
      .resize(width, height, { fit: 'cover' })
      .jpeg({ quality: 80 })
      .toFile(`output-${suffix}.jpg`);
  });
  
  await Promise.all(promises);
}

Tạo nhiều định dạng

javascript
async function generateMultipleFormats(inputPath) {
  const formats = [
    { format: 'jpeg', quality: 80, ext: 'jpg' },
    { format: 'webp', quality: 80, ext: 'webp' },
    { format: 'avif', quality: 80, ext: 'avif' }
  ];
  
  const promises = formats.map(async ({ format, quality, ext }) => {
    const image = sharp(inputPath).resize(800, 600);
    
    switch (format) {
      case 'jpeg':
        await image.jpeg({ quality }).toFile(`output.${ext}`);
        break;
      case 'webp':
        await image.webp({ quality }).toFile(`output.${ext}`);
        break;
      case 'avif':
        await image.avif({ quality }).toFile(`output.${ext}`);
        break;
    }
  });
  
  await Promise.all(promises);
}

Phân tích hình ảnh

Lấy thông tin thống kê hình ảnh

javascript
async function analyzeImage(filePath) {
  const metadata = await sharp(filePath).metadata();
  const stats = await sharp(filePath).stats();
  
  return {
    metadata,
    stats: {
      isOpaque: stats.isOpaque,
      dominant: stats.dominant,
      channels: stats.channels
    }
  };
}

Phát hiện loại hình ảnh

javascript
async function detectImageType(filePath) {
  const metadata = await sharp(filePath).metadata();
  
  return {
    format: metadata.format,
    hasAlpha: metadata.hasAlpha,
    isOpaque: metadata.isOpaque,
    channels: metadata.channels,
    colorSpace: metadata.space
  };
}

Cắt nâng cao

Cắt thông minh

javascript
async function smartCrop(inputPath, outputPath, width, height) {
  // Lấy thông tin hình ảnh
  const metadata = await sharp(inputPath).metadata();
  
  // Tính toán vùng cắt
  const aspectRatio = width / height;
  const imageAspectRatio = metadata.width / metadata.height;
  
  let cropWidth, cropHeight, left, top;
  
  if (aspectRatio > imageAspectRatio) {
    // Mục tiêu rộng hơn, lấy chiều cao làm chuẩn
    cropHeight = metadata.height;
    cropWidth = cropHeight * aspectRatio;
    top = 0;
    left = (metadata.width - cropWidth) / 2;
  } else {
    // Mục tiêu cao hơn, lấy chiều rộng làm chuẩn
    cropWidth = metadata.width;
    cropHeight = cropWidth / aspectRatio;
    left = 0;
    top = (metadata.height - cropHeight) / 2;
  }
  
  await sharp(inputPath)
    .extract({ left: Math.round(left), top: Math.round(top), width: Math.round(cropWidth), height: Math.round(cropHeight) })
    .resize(width, height)
    .toFile(outputPath);
}

Tối ưu hóa hình ảnh

Tự động tối ưu hóa

javascript
async function autoOptimize(inputPath, outputPath) {
  const metadata = await sharp(inputPath).metadata();
  
  let image = sharp(inputPath);
  
  // Chọn định dạng tốt nhất theo loại hình ảnh
  if (metadata.hasAlpha) {
    // Có độ trong suốt, sử dụng PNG
    image = image.png();
  } else {
    // Không có độ trong suốt, sử dụng JPEG
    image = image.jpeg({ quality: 80, progressive: true });
  }
  
  await image.toFile(outputPath);
}

JPEG lũy tiến

javascript
await sharp('input.jpg')
  .jpeg({ 
    quality: 80, 
    progressive: true,
    mozjpeg: true 
  })
  .toFile('output.jpg');

Xử lý hàng loạt nâng cao

Watermark hàng loạt

javascript
const fs = require('fs').promises;

async function batchWatermark(inputDir, outputDir, watermarkPath) {
  const files = await fs.readdir(inputDir);
  
  for (const file of files) {
    if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
      try {
        await sharp(path.join(inputDir, file))
          .composite([
            {
              input: watermarkPath,
              top: 10,
              left: 10
            }
          ])
          .jpeg({ quality: 80 })
          .toFile(path.join(outputDir, `watermarked_${file}`));
        
        console.log(`Hoàn tất thêm watermark: ${file}`);
      } catch (error) {
        console.error(`Xử lý thất bại ${file}:`, error.message);
      }
    }
  }
}

Chuyển đổi và tối ưu hóa định dạng hàng loạt

javascript
async function batchOptimize(inputDir, outputDir) {
  const files = await fs.readdir(inputDir);
  
  for (const file of files) {
    if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
      try {
        const metadata = await sharp(path.join(inputDir, file)).metadata();
        const image = sharp(path.join(inputDir, file));
        
        // Chọn định dạng tốt nhất theo đặc tính hình ảnh
        if (metadata.hasAlpha) {
          await image.png({ compressionLevel: 9 }).toFile(path.join(outputDir, file.replace(/\.[^.]+$/, '.png')));
        } else {
          await image.jpeg({ quality: 80, progressive: true }).toFile(path.join(outputDir, file.replace(/\.[^.]+$/, '.jpg')));
        }
        
        console.log(`Tối ưu hóa hoàn tất: ${file}`);
      } catch (error) {
        console.error(`Xử lý thất bại ${file}:`, error.message);
      }
    }
  }
}

Liên kết liên quan

Được phát hành theo Giấy phép Apache 2.0.