gongxiangp2/lib/image-processor.ts
chenpei 6377ce6d24 feat: Change preview card dimensions from 300x500 to 300x400
- Update card height from 500px to 400px in homepage
- Adjust maxHeight in image processor from 1000px to 800px
- Update all processImage calls to use maxHeight: 800
- Optimized for better display ratio on homepage
2025-10-26 17:45:46 +08:00

94 lines
2.6 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 // 最大宽度(像素)
maxHeight?: 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像素
maxHeight = 800, // 默认800像素(适配300x400显示)
format = 'webp', // 默认webP格式
} = options
try {
// 获取原始图片信息
const image = sharp(buffer)
const metadata = await image.metadata()
// 计算新尺寸(保持比例,同时限制宽度和高度)
let width = metadata.width || maxWidth
let height = metadata.height || maxHeight
// 如果宽度超过限制
if (width > maxWidth) {
const ratio = maxWidth / width
width = maxWidth
height = Math.round(height * ratio)
}
// 如果高度超过限制,再次调整
if (height > maxHeight) {
const ratio = maxHeight / height
height = maxHeight
width = Math.round(width * 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`
}