gongxiangp2/lib/image-processor.ts
2025-10-26 09:11:04 +08:00

86 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sharp from 'sharp'
interface ProcessImageOptions {
maxSizeKB?: number // 最大文件大小(KB)
maxWidth?: number // 最大宽度(像素)
format?: 'webp' | 'jpeg' | 'png'
}
/**
* 处理图片:压缩、调整尺寸、转换格式
* @param buffer 原始图片buffer
* @param options 处理选项
* @returns 处理后的图片buffer
*/
export async function processImage(
buffer: Buffer,
options: ProcessImageOptions = {}
): Promise<Buffer> {
const {
maxSizeKB = 300, // 默认300KB
maxWidth = 600, // 默认600像素
format = 'webp', // 默认webP格式
} = options
try {
// 获取原始图片信息
const image = sharp(buffer)
const metadata = await image.metadata()
// 计算新尺寸(保持比例)
let width = metadata.width || maxWidth
let height = metadata.height
if (width > maxWidth) {
const ratio = maxWidth / width
width = maxWidth
if (height) {
height = Math.round(height * ratio)
}
}
// 初始质量
let quality = 80
let processedBuffer: Buffer
// 第一次处理
processedBuffer = await image
.resize(width, height, {
fit: 'inside',
withoutEnlargement: true,
})
.webp({ quality })
.toBuffer()
// 如果文件还是太大,逐步降低质量
const maxBytes = maxSizeKB * 1024
while (processedBuffer.length > maxBytes && quality > 20) {
quality -= 10
processedBuffer = await sharp(buffer)
.resize(width, height, {
fit: 'inside',
withoutEnlargement: true,
})
.webp({ quality })
.toBuffer()
}
console.log(`图片处理完成: ${metadata.width}x${metadata.height} -> ${width}x${height}, ${(buffer.length / 1024).toFixed(2)}KB -> ${(processedBuffer.length / 1024).toFixed(2)}KB, 质量: ${quality}`)
return processedBuffer
} catch (error) {
console.error('图片处理失败:', error)
throw new Error('图片处理失败')
}
}
/**
* 获取处理后的文件名(添加.webp扩展名)
*/
export function getProcessedFileName(originalName: string): string {
const nameWithoutExt = originalName.replace(/\.[^/.]+$/, '')
return `${nameWithoutExt}.webp`
}