import sharp from 'sharp' import { readdir, stat, rename, unlink } from 'fs/promises' import { join, extname } from 'path' const IMAGE_DIR = 'src/assets/images' const IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg'] // 计算文件大小(KB) function formatSize(bytes) { return (bytes / 1024).toFixed(2) + ' KB' } // 压缩单个图片 async function compressImage(fileName) { const ext = extname(fileName).toLowerCase() const inputPath = join(IMAGE_DIR, fileName) const tempPath = join(IMAGE_DIR, 'temp_' + fileName) try { const inputStats = await stat(inputPath) const inputSize = inputStats.size let pipeline = sharp(inputPath) // 根据图片类型设置压缩参数 if (ext === '.png') { pipeline = pipeline.png({ compressionLevel: 9, palette: true, quality: 80 }) } else if (ext === '.jpg' || ext === '.jpeg') { pipeline = pipeline.jpeg({ quality: 80, mozjpeg: true }) } // 执行压缩到临时文件 await pipeline.toFile(tempPath) // 删除原文件并重命名临时文件 await unlink(inputPath) await rename(tempPath, inputPath) const outputStats = await stat(inputPath) const outputSize = outputStats.size const savings = ((inputSize - outputSize) / inputSize * 100).toFixed(1) console.log(`✅ ${fileName}`) console.log(` 原始:${formatSize(inputSize)} → 压缩后:${formatSize(outputSize)} (节省 ${savings}%)`) return { inputSize, outputSize, savings } } catch (error) { console.error(`❌ 压缩失败 ${fileName}:`, error.message) // 清理临时文件(如果存在) try { await unlink(tempPath) } catch (e) { // 忽略 } return null } } // 主函数 async function main() { console.log('🚀 开始压缩图片...\n') const files = await readdir(IMAGE_DIR) const imageFiles = files.filter(file => IMAGE_EXTENSIONS.includes(extname(file).toLowerCase()) ) if (imageFiles.length === 0) { console.log('⚠️ 未找到需要压缩的图片') return } console.log(`📁 找到 ${imageFiles.length} 张图片\n`) let totalInput = 0 let totalOutput = 0 let successCount = 0 for (const file of imageFiles) { const result = await compressImage(file) if (result) { totalInput += result.inputSize totalOutput += result.outputSize successCount++ console.log() } } const totalSavings = ((totalInput - totalOutput) / totalInput * 100).toFixed(1) console.log('='.repeat(50)) console.log(`📊 压缩完成!`) console.log(` 成功:${successCount}/${imageFiles.length} 张`) console.log(` 原始总大小:${formatSize(totalInput)}`) console.log(` 压缩后总大小:${formatSize(totalOutput)}`) console.log(` 总计节省:${totalSavings}% (${formatSize(totalInput - totalOutput)})`) console.log('='.repeat(50)) } // 运行 main().catch(console.error)