Skip to content

實用工具 API

Sharp 提供了多種實用工具函數,用於輔助圖像處理和格式轉換。

格式檢測

檢測支持的格式

javascript
import sharp from 'sharp';

// 獲取支持的輸入格式
console.log('支持的輸入格式:', sharp.format);

// 獲取支持的輸出格式
console.log('支持的輸出格式:', sharp.format);

檢查文件格式

javascript
async function checkImageFormat(filePath) {
  try {
    const metadata = await sharp(filePath).metadata();
    return {
      format: metadata.format,
      width: metadata.width,
      height: metadata.height,
      channels: metadata.channels
    };
  } catch (error) {
    return { error: error.message };
  }
}

顏色空間

顏色空間常量

javascript
// 可用的顏色空間
sharp.colourspace.srgb      // sRGB
sharp.colourspace.rgb       // RGB
sharp.colourspace.cmyk      // CMYK
sharp.colourspace.grey      // 灰度
sharp.colourspace.multiband // 多波段
sharp.colourspace.lab       // Lab
sharp.colourspace.xyz       // XYZ
sharp.colourspace.ycbcr     // YCbCr

顏色空間轉換

javascript
// 轉換為灰度
sharp('input.jpg')
  .grayscale()
  .toFile('output.jpg');

// 轉換為 CMYK
sharp('input.jpg')
  .toColourspace(sharp.colourspace.cmyk)
  .tiff()
  .toFile('output.tiff');

內核和濾鏡

調整內核

javascript
// 可用的調整內核
sharp.kernel.nearest      // 最近鄰
sharp.kernel.cubic        // 三次插值
sharp.kernel.mitchell     // Mitchell-Netravali
sharp.kernel.lanczos2     // Lanczos 2-lobed
sharp.kernel.lanczos3     // Lanczos 3-lobed (默認)

使用自定義內核

javascript
// 使用自定義調整內核
sharp('input.jpg')
  .resize(300, 200, { kernel: sharp.kernel.lanczos3 })
  .toFile('output.jpg');

位置常量

位置選項

javascript
// 可用的位置選項
sharp.position.top         // 頂部
sharp.position.right       // 右側
sharp.position.bottom      // 底部
sharp.position.left        // 左側
sharp.position.center      // 中心 (默認)
sharp.position.centre      // 中心 (英式拼寫)
sharp.position.north       // 北 (頂部)
sharp.position.east        // 東 (右側)
sharp.position.south       // 南 (底部)
sharp.position.west        // 西 (左側)
sharp.position.northeast   // 東北
sharp.position.southeast   // 東南
sharp.position.southwest   // 西南
sharp.position.northwest   // 西北

通道操作

通道常量

javascript
// 通道常量
sharp.channel.red          // 紅色通道
sharp.channel.green        // 綠色通道
sharp.channel.blue         // 藍色通道
sharp.channel.alpha        // 透明度通道
sharp.channel.grey         // 灰度通道

通道操作

javascript
// 提取紅色通道
sharp('input.jpg')
  .extractChannel(sharp.channel.red)
  .toFile('red-channel.jpg');

// 提取所有通道
const channels = await sharp('input.jpg').separate();

錯誤處理

錯誤類型

javascript
// 常見的 Sharp 錯誤
sharp.errors.InputError     // 輸入錯誤
sharp.errors.ProcessError   // 處理錯誤
sharp.errors.OutputError    // 輸出錯誤

錯誤處理示例

javascript
try {
  await sharp('input.jpg')
    .resize(300, 200)
    .toFile('output.jpg');
} catch (error) {
  if (error instanceof sharp.errors.InputError) {
    console.error('輸入文件錯誤:', error.message);
  } else if (error instanceof sharp.errors.ProcessError) {
    console.error('處理錯誤:', error.message);
  } else if (error instanceof sharp.errors.OutputError) {
    console.error('輸出錯誤:', error.message);
  } else {
    console.error('未知錯誤:', error.message);
  }
}

性能監控

內存使用

javascript
// 獲取 Sharp 內存使用情況
const stats = sharp.cache();
console.log('緩存統計:', stats);

// 清空緩存
sharp.cache(false);

並發控制

javascript
// 設置並發限制
sharp.concurrency(4); // 最多4個並發操作

// 獲取當前並發數
console.log('當前並發數:', sharp.concurrency());

工具函數

創建測試圖像

javascript
// 創建純色圖像
const redImage = sharp({
  create: {
    width: 300,
    height: 200,
    channels: 3,
    background: { r: 255, g: 0, b: 0 }
  }
});

// 創建漸變圖像
const gradient = sharp({
  create: {
    width: 300,
    height: 200,
    channels: 3,
    background: { r: 0, g: 0, b: 0 }
  }
});

圖像合成

javascript
// 合成多個圖像
const composite = await sharp('background.jpg')
  .composite([
    {
      input: 'overlay.png',
      top: 100,
      left: 100
    }
  ])
  .jpeg()
  .toBuffer();

批量處理工具

批量調整大小

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

async function batchResize(inputDir, outputDir, width, height) {
  const files = await fs.readdir(inputDir);
  
  for (const file of files) {
    if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
      try {
        await sharp(`${inputDir}/${file}`)
          .resize(width, height)
          .jpeg({ quality: 80 })
          .toFile(`${outputDir}/${file}`);
        
        console.log(`處理完成: ${file}`);
      } catch (error) {
        console.error(`處理失敗 ${file}:`, error.message);
      }
    }
  }
}

批量格式轉換

javascript
async function batchConvert(inputDir, outputDir, format) {
  const files = await fs.readdir(inputDir);
  
  for (const file of files) {
    if (file.match(/\.(jpg|jpeg|png|webp)$/i)) {
      const outputFile = file.replace(/\.[^.]+$/, `.${format}`);
      
      try {
        const image = sharp(`${inputDir}/${file}`);
        
        switch (format) {
          case 'jpg':
          case 'jpeg':
            await image.jpeg({ quality: 80 }).toFile(`${outputDir}/${outputFile}`);
            break;
          case 'png':
            await image.png().toFile(`${outputDir}/${outputFile}`);
            break;
          case 'webp':
            await image.webp({ quality: 80 }).toFile(`${outputDir}/${outputFile}`);
            break;
          case 'avif':
            await image.avif({ quality: 80 }).toFile(`${outputDir}/${outputFile}`);
            break;
        }
        
        console.log(`轉換完成: ${file} -> ${outputFile}`);
      } catch (error) {
        console.error(`轉換失敗 ${file}:`, error.message);
      }
    }
  }
}

驗證工具

驗證圖像完整性

javascript
async function validateImage(filePath) {
  try {
    const metadata = await sharp(filePath).metadata();
    
    // 檢查基本屬性
    if (!metadata.width || !metadata.height) {
      return { valid: false, error: '缺少尺寸信息' };
    }
    
    if (metadata.width <= 0 || metadata.height <= 0) {
      return { valid: false, error: '無效的尺寸' };
    }
    
    if (!metadata.format) {
      return { valid: false, error: '缺少格式信息' };
    }
    
    // 嘗試處理圖像
    await sharp(filePath).resize(1, 1).toBuffer();
    
    return { valid: true, metadata };
  } catch (error) {
    return { valid: false, error: error.message };
  }
}

檢查文件大小

javascript
const fs = require('fs');

function checkFileSize(filePath, maxSize = 10 * 1024 * 1024) { // 10MB
  const stats = fs.statSync(filePath);
  const sizeInMB = stats.size / (1024 * 1024);
  
  return {
    size: stats.size,
    sizeInMB,
    isValid: stats.size <= maxSize,
    maxSizeInMB: maxSize / (1024 * 1024)
  };
}

相關鏈接

基於 Apache 2.0 許可證發布