基于著名的 Luban Android 版本 实现的鸿蒙 ArkTS 图片压缩库,完美仿照微信朋友圈的图片压缩算法,为鸿蒙生态提供高效的图片压缩解决方案。
- 🚀 高性能压缩: 基于微信朋友圈压缩算法,提供高效的图片压缩
- 🔧 灵活配置: 支持多种压缩参数和过滤器配置
- 📱 鸿蒙原生: 专为鸿蒙系统设计,使用 ArkTS 开发
- 🎯 链式调用: 提供流畅的链式 API,使用简单
- 🔄 异步处理: 支持异步压缩,不阻塞主线程
- 📊 详细回调: 提供完整的压缩过程回调
- 🎨 透明通道: 支持保留 PNG/WebP 的透明通道
- 📁 批量处理: 支持批量压缩多个图片
- 🔍 智能过滤: 提供多种过滤器和自定义过滤功能
ohpm install @ark/luban
import { Luban } from '@ark/luban';
// 压缩单张图片
Luban.with('/path/to/image.jpg')
.launch()
.then(() => console.log('压缩完成'))
.catch(error => console.error('压缩失败:', error));
import { Luban, LubanUtils } from 'library';
// 批量压缩多张图片
Luban.with(['/path/to/image1.jpg', '/path/to/image2.png'])
.filter((path) => !path.endsWith('.gif')) // 使用函数过滤器排除 GIF
.ignoreBy(200) // 忽略小于 200KB 的图片
.setTargetDir('/custom/output/dir') // 自定义输出目录
.onStart(() => console.log('开始压缩...'))
.onSuccess((filePath) => console.log('压缩成功:', filePath))
.onError((error) => console.error('压缩失败:', error))
.launch();
import { Luban } from '@ark/luban';
async function compressImages() {
try {
const compressedFiles = await Luban.with('/path/to/image.jpg')
.ignoreBy(100)
.get();
console.log('压缩后的文件:', compressedFiles);
} catch (error) {
console.error('压缩失败:', error);
}
}
创建 Luban 构建器实例。
// 单文件
const builder = Luban.with('/path/to/image.jpg');
// 多文件
const builder = Luban.with([
'/path/to/image1.jpg',
'/path/to/image2.png'
]);
Luban.compress(sourcePath: string, targetPath?: string, options?: CompressOptions): Promise<CompressResult>
快速压缩单张图片。
const result = await Luban.compress(
'/path/to/source.jpg',
'/path/to/target.jpg',
{ focusAlpha: true }
);
Luban.with(paths)
.filter((path) => path.endsWith('.jpg')) // 设置过滤器
.ignoreBy(100) // 忽略小于 100KB 的文件
.setFocusAlpha(true) // 保留透明通道
.setTargetDir('/output/dir') // 设置输出目录
.launch();
Luban.with(paths)
.onStart(() => {
// 开始压缩
})
.onSuccess((filePath) => {
// 单个文件压缩成功
})
.onError((error) => {
// 发生错误
})
.onRename((filePath) => {
// 自定义压缩后的文件名
return `compressed_${Date.now()}.jpg`;
})
.launch();
// 简单过滤器
.filter((path) => path.endsWith('.jpg'))
// 复杂过滤器
.filter((path) => {
const isImage = path.match(/\.(jpg|jpeg|png|webp)$/i);
const isLarge = LubanUtils.getFileSizeInKBSync(path) > 1024;
return isImage && isLarge;
})
import { LubanUtils } from '@ark/luban';
// 只压缩图片
.filter(LubanUtils.FILTERS.IMAGES_ONLY)
// 排除 GIF
.filter(LubanUtils.FILTERS.EXCLUDE_GIF)
// 大于指定大小
.filter(LubanUtils.FILTERS.MIN_SIZE(500)) // 500KB
// 默认过滤器(排除GIF且大于100KB)
.filter(LubanUtils.FILTERS.DEFAULT())
import { LubanUtils } from '@ark/luban';
// 检查是否为图片
LubanUtils.isImage(path);
// 获取文件大小
const sizeKB = LubanUtils.getFileSizeInKBSync(path);
// 格式化文件大小
const size = LubanUtils.formatFileSize(bytes);
Luban.with(paths)
// 自定义过滤规则
.filter((path) => {
const extension = path.toLowerCase().split('.').pop();
const size = LubanUtils.getFileSizeInKBSync(path);
return ['jpg', 'png'].includes(extension) && size > 500;
})
// 自定义输出文件名
.onRename((path) => {
const original = path.split('/').pop();
return `compressed_${Date.now()}_${original}`;
})
// 处理压缩结果
.onSuccess(async (filePath) => {
const originalSize = await LubanUtils.getFileSizeInKB(path);
const compressedSize = await LubanUtils.getFileSizeInKB(filePath);
const ratio = LubanUtils.calculateCompressRatio(originalSize, compressedSize);
console.log(`压缩率: ${ratio}%`);
})
.launch();
async function compressInBatches(paths: string[]) {
const batchSize = 3; // 每批处理3张
const batches = [];
for (let i = 0; i < paths.length; i += batchSize) {
const batch = paths.slice(i, i + batchSize);
batches.push(
Luban.with(batch)
.filter(LubanUtils.FILTERS.DEFAULT())
.get()
);
}
const results = await Promise.all(batches);
return results.flat();
}
- 合理设置阈值
// 根据实际需求设置忽略阈值
Luban.with(paths)
.ignoreBy(200) // 忽略小于200KB的图片
.launch();
- 使用适当的过滤器
// 组合多个条件
.filter((path) => {
const isImage = LubanUtils.isImage(path);
const isNotGif = !path.endsWith('.gif');
const isLarge = LubanUtils.getFileSizeInKBSync(path) > 500;
return isImage && isNotGif && isLarge;
})
- 错误处理
Luban.with(paths)
.onError((error) => {
console.error('压缩错误:', error);
// 可以在这里实现重试逻辑
})
.launch()
.catch((error) => {
console.error('整体流程错误:', error);
// 处理致命错误
});
- 资源清理
// 压缩完成后清理临时文件
.onSuccess(async (filePath) => {
// 处理压缩后的文件
await processCompressedFile(filePath);
// 清理临时文件
LubanUtils.cleanupTempFiles();
})
Luban.with('/path/to/transparent.png')
.setFocusAlpha(true) // 启用透明通道支持
.launch();
Luban.with(paths)
.onRename((path) => {
const timestamp = Date.now();
const original = path.split('/').pop();
return `compressed_${timestamp}_${original}`;
})
.launch();
// 使用批量处理并显示进度
async function compressWithProgress(paths: string[]) {
let processed = 0;
const total = paths.length;
await Luban.with(paths)
.onSuccess(() => {
processed++;
const progress = (processed / total) * 100;
console.log(`进度: ${progress.toFixed(1)}%`);
})
.launch();
}
欢迎提交 Issue 和 Pull Request!
本项目采用 Apache 2.0 许可证。