@simon_he/browser-compress-image
v1.0.8
Published
🚀 A powerful, lightweight browser image compression library with TypeScript support. Compress JPEG, PNG, GIF images with multiple output formats (Blob, File, Base64, ArrayBuffer) and zero dependencies.
Downloads
92
Maintainers
Readme
Browser Compress Image
🎯 多工具压缩 - 自动选择最优结果
import { compressWithMultipleTools } from '@simon_he/browser-compress-image'
// 使用多种压缩工具并行处理,自动选择最优结果
const result = await compressWithMultipleTools(file, {
quality: 0.8,
tools: ['browser-image-compression', 'compressorjs', 'canvas'],
})
console.log('最优压缩工具:', result.bestTool)
console.log('压缩后文件:', result.compressedFile)
console.log('所有结果:', result.results)📊 压缩性能统计
import { compressWithStats } from '@simon_he/browser-compress-image'
// 获取详细的压缩统计信息,包括耗时和性能数据
const stats = await compressWithStats(file, { quality: 0.8 })
console.log('压缩统计:', {
bestTool: stats.bestTool, // 最优工具: "canvas"
originalSize: stats.originalSize, // 原始大小: 1024000 bytes
compressedSize: stats.compressedSize, // 压缩后大小: 512000 bytes
compressionRatio: stats.compressionRatio, // 压缩比例: 50%
totalDuration: stats.totalDuration, // 总耗时: 1200ms
toolsUsed: stats.toolsUsed, // 各工具详细性能数据
})
// 性能对比表格会在控制台自动显示
// ┌─────────┬──────────────────────┬───────────────┬──────────────┬─────────────┐
// │ (index) │ Tool │ Size (bytes) │ Reduction (%)│ Duration │
// ├─────────┼──────────────────────┼───────────────┼──────────────┼─────────────┤
// │ 0 │ 'canvas' │ 512000 │ '50.0%' │ '800ms' │
// │ 1 │ 'browser-compression'│ 520000 │ '49.2%' │ '1200ms' │
// └─────────┴──────────────────────┴───────────────┴──────────────┴─────────────┘🚀 Browser Compress Image
✨ 特性
🎯 核心功能
- 多格式支持 - JPEG、PNG、GIF、WebP 全覆盖
- 多输出类型 - Blob、File、Base64、ArrayBuffer 任你选择
- 多工具引擎 - 集成 CompressorJS、Canvas、browser-image-compression 等多种压缩算法
- 智能优选 - 自动比对多工具压缩结果,选择最优质量与体积的方案
� 上传方式
- 拖拽上传 - 支持单文件/多文件拖拽,PC 和移动端友好
- 粘贴上传 - 直接 Ctrl+V 粘贴图片,快速便捷
- 文件夹上传 - 一键选择文件夹,批量处理图片
- 批量处理 - 同时处理多个图片文件,并行压缩
🔧 技术特性
- 轻量级 - 体积小巧,性能优异
- TypeScript - 完整类型支持,开发体验极佳
- 现代化 API - 简洁易用的 async/await 接口
- 高性能 - 基于 WebWorker 的并行处理
- 灵活配置 - 自定义压缩质量和输出格式
- 智能过滤 - 根据 EXIF 需求自动选择合适的压缩工具
- 多结果比较 - 支持返回所有工具的压缩结果进行性能分析
🏆 为什么选择我们?
| 特性 | 我们 | 其他库 | | --------------- | ---- | ------ | | 多输出格式 | ✅ | ❌ | | 多工具引擎比对 | ✅ | ❌ | | TypeScript 支持 | ✅ | 部分 | | GIF/WebP 压缩 | ✅ | 很少 | | 批量/粘贴上传 | ✅ | ❌ | | 文件夹上传 | ✅ | ❌ | | 零配置使用 | ✅ | ❌ | | 文档完善 | ✅ | 一般 |
📦 安装
# npm
npm install @simon_he/browser-compress-image
# yarn
yarn add @simon_he/browser-compress-image
# pnpm
pnpm add @simon_he/browser-compress-image🚀 快速开始
基础用法
import { compress } from '@simon_he/browser-compress-image'
// 压缩图片,默认返回 Blob
const compressedBlob = await compress(file, 0.6)
console.log('压缩完成!', compressedBlob)
// 保留 EXIF 信息的压缩
const compressedWithExif = await compress(file, {
quality: 0.8,
preserveExif: true,
})🎯 多工具压缩 - 自动选择最优结果
import { compress } from '@simon_he/browser-compress-image'
// 默认行为:自动选择最优结果
const compressedBlob = await compress(file, {
quality: 0.8,
preserveExif: true,
})
// 获取所有工具的压缩结果进行比较
const allResults = await compress(file, {
quality: 0.8,
returnAllResults: true, // 返回所有工具的结果
type: 'blob',
})
console.log('最优工具:', allResults.bestTool)
console.log('最优结果:', allResults.bestResult)
console.log('所有结果:')
allResults.allResults.forEach((result) => {
console.log(
`${result.tool}: ${result.compressedSize} bytes (${result.compressionRatio.toFixed(1)}% reduction)`,
)
})📁 多文件批量处理
// 批量压缩多个文件
const files = Array.from(fileInput.files)
const compressedFiles = await Promise.all(
files.map((file) => compress(file, 0.7, 'file')),
)📋 粘贴上传
// 监听粘贴事件
document.addEventListener('paste', async (e) => {
const items = Array.from(e.clipboardData?.items || [])
const imageItems = items.filter((item) => item.type.startsWith('image/'))
for (const item of imageItems) {
const file = item.getAsFile()
if (file) {
const compressed = await compress(file, 0.6)
// 处理压缩后的图片
}
}
})📂 文件夹上传
<!-- HTML 中设置 webkitdirectory 属性 -->
<input
type="file"
webkitdirectory
multiple
accept="image/*"
@change="handleFolderUpload"
/>
````typescript const handleFolderUpload = async (event: Event) => { const files
= Array.from((event.target as HTMLInputElement).files || []) const imageFiles =
files.filter(file => file.type.startsWith('image/')) //
批量压缩文件夹中的所有图片 const results = await Promise.all(
imageFiles.map(async file => ({ original: file, compressed: await compress(file,
0.7, 'file'), path: file.webkitRelativePath })) ) } ### 🎨 多种输出格式
```typescript // 🔹 返回 Blob (默认) const blob = await compress(file, 0.6,
'blob') // 🔹 返回 File 对象,保留文件名 const file = await
compress(originalFile, 0.6, 'file') // 🔹 返回 Base64 字符串,直接用于 img src
const base64 = await compress(file, 0.6, 'base64') // 🔹 返回
ArrayBuffer,用于进一步处理 const arrayBuffer = await compress(file, 0.6,
'arrayBuffer')🎯 实际应用场景
📸 上传前压缩
const handleUpload = async (file: File) => {
// 压缩为 File 对象,保留原文件名
const compressedFile = await compress(file, 0.7, 'file')
const formData = new FormData()
formData.append('image', compressedFile)
await fetch('/api/upload', {
method: 'POST',
body: formData,
})
}🖼️ 图片预览
const showPreview = async (file: File) => {
// 压缩为 Base64,直接显示
const base64 = await compress(file, 0.6, 'base64')
const img = document.createElement('img')
img.src = base64
document.body.appendChild(img)
}💾 数据处理
const processImageData = async (file: File) => {
// 压缩为 ArrayBuffer,进行二进制处理
const buffer = await compress(file, 0.8, 'arrayBuffer')
// 发送到 WebSocket 或进行其他二进制操作
websocket.send(buffer)
}📚 API 文档
compress 函数
compress<T extends CompressResultType = 'blob'>(
file: File, // 要压缩的图片文件
quality?: number, // 压缩质量 (0-1),默认 0.6
type?: T // 输出格式,默认 'blob'
): Promise<CompressResult<T>>compressWithStats 函数
compressWithStats(
file: File, // 要压缩的图片文件
options?: CompressOptions // 压缩选项(可选)
): Promise<CompressionStats>返回详细的压缩统计信息,包括:
interface CompressionStats {
bestTool: string // 最优压缩工具名称
compressedFile: Blob // 最优压缩结果
originalSize: number // 原始文件大小(字节)
compressedSize: number // 压缩后大小(字节)
compressionRatio: number // 压缩比例(百分比)
totalDuration: number // 总耗时(毫秒)
toolsUsed: Array<{
// 各工具详细信息
tool: string // 工具名称
size: number // 压缩后大小
duration: number // 耗时
compressionRatio: number // 压缩比例
success: boolean // 是否成功
error?: string // 错误信息(如果失败)
}>
}🛠️ 支持的压缩工具
| 工具 | 标识符 | 适用格式 | EXIF支持 | 特点 |
| ------------------------- | ----------------------------- | --------- | -------- | ------------------------ |
| Browser Image Compression | 'browser-image-compression' | JPEG, PNG | ✅ | 快速压缩,兼容性好 |
| CompressorJS | 'compressorjs' | JPEG, PNG | ⚠️ | 轻量级,配置灵活 |
| Canvas | 'canvas' | 所有格式 | ❌ | 原生浏览器 API,通用性强 |
| Gifsicle | 'gifsicle' | GIF | N/A | GIF 专用压缩引擎 |
EXIF 支持说明:
- ✅ 完全支持:可以完整保留 EXIF 信息
- ⚠️ 部分支持:可以保留基本信息,但可能会丢失某些元数据
- ❌ 不支持:压缩过程会移除所有 EXIF 信息
- N/A 不适用:该格式通常不包含 EXIF 信息
📸 EXIF 信息处理
当设置 preserveExif: true 时,库会自动进行智能工具过滤:
| 工具 | EXIF 支持 | 说明 | | ------------------------- | --------- | ---------------------- | | browser-image-compression | ✅ | 原生支持 EXIF 保留 | | CompressorJS | ✅ | 支持 EXIF 保留 | | Canvas | ❌ | 不支持(会被自动过滤) | | gifsicle | ❌ | 不支持(会被自动过滤) |
智能过滤机制:
- 当
preserveExif: true时,系统自动过滤掉 Canvas 和 gifsicle 工具 - 确保只使用支持 EXIF 保留的工具进行压缩
- 如果没有可用的 EXIF 支持工具,会抛出错误提示用户调整参数
// EXIF 信息会被保留,只使用 browser-image-compression 和 CompressorJS
const result = await compress(file, {
quality: 0.8,
preserveExif: true, // 自动过滤不支持 EXIF 的工具
})
// 注意:GIF 格式不支持 EXIF,会抛出错误
try {
const gifResult = await compress(gifFile, {
preserveExif: true, // ❌ 会抛出错误
})
} catch (error) {
console.error('GIF files do not support EXIF preservation')
}🖼️ 支持的图片格式
- JPEG (.jpg, .jpeg) - 使用 browser-image-compression、CompressorJS、Canvas
- PNG (.png) - 使用 browser-image-compression、CompressorJS、Canvas
- WebP (.webp) - 使用 Canvas
- GIF (.gif) - 使用 gifsicle-wasm-browser
- 其他格式 - 使用 Canvas 和 CompressorJS 兜底
🔍 多工具结果比较
当设置 returnAllResults: true 时,可以获取所有压缩工具的详细结果:
interface MultipleCompressResults<T> {
bestResult: CompressResult<T> // 最优结果(文件大小最小)
bestTool: string // 最优工具名称
allResults: CompressResultItem<T>[] // 所有工具的结果
totalDuration: number // 总耗时(毫秒)
}
interface CompressResultItem<T> {
tool: string // 工具名称
result: CompressResult<T> // 压缩结果
originalSize: number // 原始大小
compressedSize: number // 压缩后大小
compressionRatio: number // 压缩比例(百分比)
duration: number // 耗时(毫秒)
success: boolean // 是否成功
error?: string // 错误信息(如果失败)
}
// 使用示例
const results = await compress(file, {
quality: 0.8,
returnAllResults: true,
type: 'blob',
})
// 分析所有工具的性能
results.allResults.forEach((item) => {
console.log(
`${item.tool}: ${item.compressedSize} bytes, ${item.compressionRatio.toFixed(1)}% reduction, ${item.duration}ms`,
)
})
// 使用最优结果
const optimizedFile = results.bestResult使用场景:
- 🔬 性能分析 - 比较不同工具在特定图片上的表现
- 📊 数据收集 - 收集压缩统计数据用于优化
- 🎯 自定义选择 - 根据特定需求(如速度优先)选择合适工具
- 🔍 调试诊断 - 分析压缩失败的原因
📋 参数说明
| 参数 | 类型 | 默认值 | 说明 |
| ------------------ | -------------------- | -------- | ------------------------------------ |
| file | File | - | 要压缩的图片文件 |
| quality | number | 0.6 | 压缩质量,范围 0-1,值越小文件越小 |
| type | CompressResultType | 'blob' | 输出格式类型 |
| preserveExif | boolean | false | 是否保留 EXIF 信息(仅部分工具支持) |
| returnAllResults | boolean | false | 是否返回所有工具的压缩结果 |
🎯 支持的输出格式
| 格式 | 类型 | 说明 | 使用场景 |
| --------------- | ------------- | -------------------- | ------------------- |
| 'blob' | Blob | 二进制对象 | 文件上传、存储 |
| 'file' | File | 文件对象,保留文件名 | 表单提交、文件系统 |
| 'base64' | string | Base64 编码字符串 | 图片显示、数据传输 |
| 'arrayBuffer' | ArrayBuffer | 二进制数据缓冲区 | WebSocket、底层处理 |
🎨 UI 交互功能
📱 移动端和桌面端优化
- 智能拖拽 - 拖拽时自动隐藏信息层,提升视觉体验
- 响应式设计 - 完美适配各种屏幕尺寸
- 触摸友好 - 移动端手势操作优化
📊 压缩统计显示
- 实时统计 - 显示原始大小、压缩后大小、节省空间
- 压缩比例 - 负数用红色显示,正数用绿色显示
- 批量统计 - 多文件压缩时显示总体统计信息
TypeScript 类型支持
import type {
CompressResultType,
CompressResult,
} from '@simon_he/browser-compress-image'
// 类型会根据第三个参数自动推断
const blob = await compress(file, 0.6, 'blob') // 类型: Blob
const file2 = await compress(file, 0.6, 'file') // 类型: File
const base64 = await compress(file, 0.6, 'base64') // 类型: string
const buffer = await compress(file, 0.6, 'arrayBuffer') // 类型: ArrayBuffer📊 压缩效果对比
🤝 贡献
我们欢迎任何形式的贡献!
- Fork 这个项目
- 创建你的特性分支 (
git checkout -b feature/AmazingFeature) - 提交你的更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开一个 Pull Request
🙏 致谢
本项目基于以下优秀的开源库构建:
核心压缩引擎
- browser-image-compression - 浏览器图片压缩核心
- compressorjs - 轻量级图片压缩库
- gifsicle-wasm-browser - GIF 专用压缩支持
开发工具
- Vue 3 - 渐进式 JavaScript 框架
- Vite - 现代化构建工具
- TypeScript - 类型安全的 JavaScript
- UnoCSS - 即时原子化 CSS 引擎
📄 许可证
MIT License © 2022-2025 Simon He
