# image-compressor
**Repository Path**: qqcode/image-compressor
## Basic Information
- **Project Name**: image-compressor
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-06-26
- **Last Updated**: 2026-06-26
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 图片压缩工具(浏览器端)
> 一套高质量的前端图片压缩方案,采用竞品级压缩策略,支持智能格式识别、透明度检测、动图保护,并内置防膨胀保护,确保压缩后体积绝不会超过原图。
## 特性
- **高压缩比** —— 默认压缩至 300KB 以内,质量保持 98% 的接近无损效果
- **防膨胀保护** —— 若压缩后反而变大(如原图已是高压缩比),自动返回原文件,绝不越压越大
- **智能格式处理** —— 自动检测 PNG 透明度,保留透明通道;检测 GIF 动图,保留动画
- **批量压缩** —— 支持多文件并行处理
- **高效策略** —— 针对 PNG、JPEG、GIF、WebP 采用不同压缩算法
- **错误容错** —— 压缩失败时自动返回原文件,不阻塞流程
- **统计信息** —— 返回压缩前后大小、压缩率、处理耗时
- **TypeScript 支持** —— 提供完整类型定义,可直接导入使用
## 安装
```bash
npm install @xkadmin/image-compressor
# 或
yarn add @xkadmin/image-compressor
```
## 使用
### 基础压缩
```typescript
import { compressImage, type CompressionOptions, type CompressionResult } from '@xkadmin/image-compressor';
// 类型可直接导入,用于标注变量
const options: CompressionOptions = {
maxSizeMB: 0.3, // 目标大小 300KB
quality: 0.98, // 98% 高质量
maxWidthOrHeight: 1920, // 最大宽或高 1920px
};
const fileInput = document.getElementById('fileInput') as HTMLInputElement;
fileInput.addEventListener('change', async (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
const result: CompressionResult = await compressImage(file, options);
console.log(`原始大小: ${result.originalSize} bytes`);
console.log(`压缩后: ${result.compressedSize} bytes`);
console.log(`压缩率: ${(100 - result.compressionRatio).toFixed(1)}%`);
console.log(`耗时: ${result.processingTime.toFixed(1)}ms`);
// 获取压缩后的 File 对象,可用于上传或展示
// 注意:若原图已无法进一步压缩,会自动返回原文件(compressionRatio === 100)
const compressedFile = result.file;
// 例如:formData.append('file', compressedFile)
});
```
### 批量压缩
```typescript
import { compressImages } from '@xkadmin/image-compressor';
const files = Array.from(fileInput.files || []);
const results = await compressImages(files, { maxSizeMB: 0.5 });
results.forEach((r, i) => {
console.log(`图片 ${i+1}: ${r.compressedSize} bytes`);
});
```
### 直接浏览器使用(通过 `
```
## API 文档
### `compressImage(file: File, options?: CompressionOptions): Promise`
压缩单张图片。
#### 参数 `CompressionOptions`
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `maxSizeMB` | `number` | `0.3` | 压缩后目标文件大小(MB) |
| `maxWidthOrHeight` | `number` | `1920` | 最大宽度或高度(等比缩放) |
| `quality` | `number` | `0.98` | 压缩质量,范围 `0-1`(仅对 JPEG/WebP 有效) |
| `fileType` | `string` | 自动选择 | 强制输出格式,如 `'image/jpeg'` |
| `useWebWorker` | `boolean` | `false` | (暂未实现)是否使用 Web Worker |
#### 返回值 `CompressionResult`
| 属性 | 类型 | 说明 |
|------|------|------|
| `file` | `File` | 压缩后的文件对象(无法进一步压缩时为原文件) |
| `originalSize` | `number` | 原始大小(字节) |
| `compressedSize` | `number` | 压缩后大小(字节,`<= originalSize`) |
| `compressionRatio` | `number` | 压缩后大小 / 原始大小 × 100(百分比,`100` 表示未压缩) |
| `processingTime` | `number` | 处理耗时(毫秒) |
> 防膨胀保证:`compressedSize` 永远不会超过 `originalSize`。若压缩引擎产出的结果反而变大(常见于原图已是高压缩比 JPEG、PNG 转码、小图重编码等),将自动返回原文件,此时 `compressionRatio === 100`。
---
### `compressImages(files: File[], options?: CompressionOptions): Promise`
批量压缩图片,返回结果数组。若某张图片压缩失败,会返回原文件并记录错误。
---
## 智能格式策略
| 原格式 | 条件 | 输出格式 |
|--------|------|----------|
| PNG | 有透明度 | PNG(保持透明) |
| PNG | 无透明度 | JPEG(更高压缩) |
| GIF | 动图 | GIF(保留动画) |
| GIF | 静态图 | JPEG(更高压缩) |
| WebP | 任意 | WebP(保持原格式) |
| JPEG | 任意 | JPEG(保持原格式) |
| 其他 | 任意 | JPEG(默认) |
## 注意事项
- 本工具 **仅支持浏览器环境**,依赖 `Canvas`、`FileReader` 等 Web API。
- 压缩大图片时(如 10MB+),可能耗时较长,建议在 UI 中显示加载状态。
- 若浏览器不支持 `toBlob` 的指定格式,会降级为默认格式。
- `useWebWorker` 选项当前未实现,可忽略。
## 贡献
欢迎提交 Issue 和 Pull Request。请确保代码通过 TypeScript 类型检查,并保持测试覆盖。
## License
[MIT](LICENSE) © 2026 [YiKe/XKAdmin]