| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- import sharp from 'sharp';
- import fs from 'fs';
- /**
- * 压缩图片到目标大小左右
- * @param inputPath 输入文件路径
- * @param outputPath 输出文件路径
- * @param targetSize 目标大小(字节),默认100KB
- */
- export async function compressImage(
- inputPath: string,
- outputPath: string,
- targetSize: number = 100 * 1024
- ): Promise<{ success: boolean; finalSize?: number; error?: string }> {
- try {
- let quality = 80;
- let compressedSize = targetSize + 1;
- // 获取图片信息
- const metadata = await sharp(inputPath).metadata();
- let width = metadata.width;
- let height = metadata.height;
- // 如果图片尺寸较大,先调整尺寸
- if (width && height && (width > 2000 || height > 2000)) {
- width = Math.round(width * 0.5);
- height = Math.round(height * 0.5);
- }
- while (compressedSize > targetSize && quality > 10) {
- await sharp(inputPath)
- .resize(width, height, {
- fit: 'inside',
- withoutEnlargement: true,
- })
- .jpeg({
- quality: quality,
- mozjpeg: true,
- })
- .toFile(outputPath);
- // 获取压缩后文件大小
- const stats = fs.statSync(outputPath);
- compressedSize = stats.size;
- // 如果仍然大于目标大小,降低质量继续压缩
- if (compressedSize > targetSize) {
- quality -= 15;
- if (quality < 10) quality = 10;
- }
- }
- return { success: true, finalSize: compressedSize };
- } catch (error) {
- return {
- success: false,
- error: error instanceof Error ? error.message : '压缩失败',
- };
- }
- }
|