Skip to content

输出格式 API

Sharp 支持多种图像输出格式,每种格式都有其特定的选项和用途。

JPEG 格式

基本用法

javascript
import sharp from 'sharp';

sharp('input.png')
  .jpeg()
  .toFile('output.jpg');

JPEG 选项

javascript
sharp('input.png')
  .jpeg({
    quality: 80,           // 质量 (1-100)
    progressive: false,     // 渐进式 JPEG
    chromaSubsampling: '4:4:4', // 色度子采样
    mozjpeg: false,        // 使用 mozjpeg 编码器
    trellisQuantisation: false, // 网格量化
    overshootDeringing: false,  // 过冲去振铃
    optimiseScans: false,  // 优化扫描
    quantisationTable: 0   // 量化表
  })
  .toFile('output.jpg');

质量设置

javascript
// 高质量
sharp('input.png').jpeg({ quality: 95 })

// 中等质量
sharp('input.png').jpeg({ quality: 80 })

// 低质量(小文件)
sharp('input.png').jpeg({ quality: 50 })

PNG 格式

基本用法

javascript
sharp('input.jpg')
  .png()
  .toFile('output.png');

PNG 选项

javascript
sharp('input.jpg')
  .png({
    progressive: false,     // 渐进式 PNG
    compressionLevel: 6,    // 压缩级别 (0-9)
    adaptiveFiltering: false, // 自适应滤波
    palette: false,         // 调色板模式
    quality: 100,          // 质量 (仅用于调色板模式)
    colours: 256,          // 颜色数量 (仅用于调色板模式)
    dither: 0.5,          // 抖动 (0-1)
    force: false           // 强制 PNG 输出
  })
  .toFile('output.png');

透明度处理

javascript
// 保持透明度
sharp('input.png')
  .png()
  .toFile('output.png');

// 添加白色背景
sharp('input.png')
  .flatten({ background: { r: 255, g: 255, b: 255 } })
  .png()
  .toFile('output.png');

WebP 格式

基本用法

javascript
sharp('input.jpg')
  .webp()
  .toFile('output.webp');

WebP 选项

javascript
sharp('input.jpg')
  .webp({
    quality: 80,           // 质量 (1-100)
    alphaQuality: 100,     // 透明度质量 (1-100)
    lossless: false,       // 无损压缩
    nearLossless: false,   // 近无损压缩
    smartSubsample: false, // 智能子采样
    reductionEffort: 4,    // 压缩努力 (0-6)
    mixed: false,          // 混合模式
    force: false           // 强制 WebP 输出
  })
  .toFile('output.webp');

无损 WebP

javascript
// 无损压缩
sharp('input.png')
  .webp({ lossless: true })
  .toFile('output.webp');

// 近无损压缩
sharp('input.png')
  .webp({ nearLossless: true, quality: 60 })
  .toFile('output.webp');

AVIF 格式

基本用法

javascript
sharp('input.jpg')
  .avif()
  .toFile('output.avif');

AVIF 选项

javascript
sharp('input.jpg')
  .avif({
    quality: 80,           // 质量 (1-100)
    lossless: false,       // 无损压缩
    effort: 4,             // 压缩努力 (0-6)
    chromaSubsampling: '4:4:4', // 色度子采样
    force: false           // 强制 AVIF 输出
  })
  .toFile('output.avif');

TIFF 格式

基本用法

javascript
sharp('input.jpg')
  .tiff()
  .toFile('output.tiff');

TIFF 选项

javascript
sharp('input.jpg')
  .tiff({
    quality: 80,           // 质量 (1-100)
    compression: 'jpeg',   // 压缩方式
    pyramid: false,        // 金字塔模式
    tile: false,           // 平铺模式
    tileSize: 256,         // 平铺大小
    xres: 1,              // X 分辨率
    yres: 1,              // Y 分辨率
    resolutionUnit: 'inch', // 分辨率单位
    force: false           // 强制 TIFF 输出
  })
  .toFile('output.tiff');

压缩选项

javascript
// JPEG 压缩
sharp('input.jpg').tiff({ compression: 'jpeg' })

// LZW 压缩
sharp('input.jpg').tiff({ compression: 'lzw' })

// 无压缩
sharp('input.jpg').tiff({ compression: 'none' })

// Deflate 压缩
sharp('input.jpg').tiff({ compression: 'deflate' })

原始格式 (raw)

输出原始像素数据

javascript
// 输出 RGB 原始数据
const rawData = await sharp('input.jpg')
  .raw()
  .toBuffer();

// 输出 RGBA 原始数据
const rawData = await sharp('input.jpg')
  .ensureAlpha()
  .raw()
  .toBuffer();

多格式输出

同时输出多种格式

javascript
const image = sharp('input.jpg').resize(800, 600);

// 输出多种格式
await Promise.all([
  image.clone().jpeg({ quality: 80 }).toFile('output.jpg'),
  image.clone().png().toFile('output.png'),
  image.clone().webp({ quality: 80 }).toFile('output.webp'),
  image.clone().avif({ quality: 80 }).toFile('output.avif')
]);

响应式图像

javascript
async function generateResponsiveImages(inputPath) {
  const sizes = [320, 640, 1280, 1920];
  const formats = ['jpeg', 'webp', 'avif'];
  
  const promises = [];
  
  for (const size of sizes) {
    for (const format of formats) {
      const image = sharp(inputPath).resize(size);
      
      switch (format) {
        case 'jpeg':
          promises.push(
            image.clone().jpeg({ quality: 80 })
              .toFile(`output-${size}.jpg`)
          );
          break;
        case 'webp':
          promises.push(
            image.clone().webp({ quality: 80 })
              .toFile(`output-${size}.webp`)
          );
          break;
        case 'avif':
          promises.push(
            image.clone().avif({ quality: 80 })
              .toFile(`output-${size}.avif`)
          );
          break;
      }
    }
  }
  
  await Promise.all(promises);
}

格式检测

根据文件扩展名自动选择格式

javascript
function getOutputFormat(filename) {
  const ext = filename.split('.').pop().toLowerCase();
  
  switch (ext) {
    case 'jpg':
    case 'jpeg':
      return 'jpeg';
    case 'png':
      return 'png';
    case 'webp':
      return 'webp';
    case 'avif':
      return 'avif';
    case 'tiff':
    case 'tif':
      return 'tiff';
    default:
      return 'jpeg';
  }
}

async function convertImage(inputPath, outputPath) {
  const format = getOutputFormat(outputPath);
  const image = sharp(inputPath);
  
  switch (format) {
    case 'jpeg':
      await image.jpeg({ quality: 80 }).toFile(outputPath);
      break;
    case 'png':
      await image.png().toFile(outputPath);
      break;
    case 'webp':
      await image.webp({ quality: 80 }).toFile(outputPath);
      break;
    case 'avif':
      await image.avif({ quality: 80 }).toFile(outputPath);
      break;
    case 'tiff':
      await image.tiff({ compression: 'jpeg' }).toFile(outputPath);
      break;
  }
}

性能优化

流式输出

javascript
const fs = require('fs');

// 流式处理
fs.createReadStream('input.jpg')
  .pipe(sharp().jpeg({ quality: 80 }))
  .pipe(fs.createWriteStream('output.jpg'));

内存优化

javascript
// 使用 Buffer 而不是文件
const buffer = await sharp('input.jpg')
  .jpeg({ quality: 80 })
  .toBuffer();

// 直接输出到响应
app.get('/image', async (req, res) => {
  const buffer = await sharp('input.jpg')
    .resize(300, 200)
    .jpeg({ quality: 80 })
    .toBuffer();
    
  res.set('Content-Type', 'image/jpeg');
  res.send(buffer);
});

相关链接

Released under the Apache 2.0 License.