输出格式 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);
});