扫一扫分享
纯前端图片压缩工具现在的网站几乎都离不开图片,无论是商品展示、用户头像还是内容配图。但图片体积大是个头疼的问题——既占服务器空间,又耗用户流量。compressor.js的出现正好解决了这个痛点,它能在前端直接压缩图片,再上传到服务器,大大减轻了存储和传输的压力。
简单直接:几行代码就能实现图片压缩
前端处理:不占用服务器资源,用户选择图片后立即压缩
质量可控:虽然是有损压缩,但压缩效果很理想
兼容性好:基于浏览器原生能力,主流浏览器都支持
有三种方式可以引入:
CDN方式(最简单):
<script src="https://cdn.jsdelivr.net/npm/compressorjs@1.2.1/dist/compressor.min.js"></script>npm安装:
npm install compressorjs然后在代码中引入:
import Compressor from 'compressorjs';直接下载:
从GitHub下载文件,然后本地引入。
先来看一个最基础的压缩例子:
<!DOCTYPE html>
<html>
<head>
<title>图片压缩示例</title>
</head>
<body>
<input type="file" id="imageInput" accept="image/*">
<script src="https://cdn.jsdelivr.net/npm/compressorjs@1.2.1/dist/compressor.min.js"></script>
<script>
document.getElementById('imageInput').addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
new Compressor(file, {
quality: 0.6,
success(result) {
// 压缩成功后,result就是压缩后的文件
console.log('原文件大小:', (file.size / 1024 / 1024).toFixed(2), 'MB');
console.log('压缩后大小:', (result.size / 1024 / 1024).toFixed(2), 'MB');
// 创建下载链接或上传到服务器
const url = URL.createObjectURL(result);
const a = document.createElement('a');
a.href = url;
a.download = 'compressed_' + file.name;
a.textContent = '下载压缩后的图片';
document.body.appendChild(a);
},
error(err) {
console.error('压缩失败:', err.message);
}
});
});
</script>
</body>
</html>在实际业务中,我们通常需要把压缩后的图片上传到服务器。下面是一个完整的例子:
class ImageUploader {
constructor(options = {}) {
this.maxWidth = options.maxWidth || 800;
this.maxHeight = options.maxHeight || 800;
this.quality = options.quality || 0.7;
}
// 压缩图片
compressImage(file) {
return new Promise((resolve, reject) => {
new Compressor(file, {
quality: this.quality,
maxWidth: this.maxWidth,
maxHeight: this.maxHeight,
convertSize: 1000000, // 超过1MB的图片转换为JPEG
success: resolve,
error: reject
});
});
}
// 上传到服务器
async uploadToServer(file) {
try {
const formData = new FormData();
formData.append('avatar', file, file.name);
const response = await fetch('/api/upload/avatar', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('上传失败');
}
return await response.json();
} catch (error) {
throw new Error('上传过程中出错: ' + error.message);
}
}
// 处理文件选择
async handleFileSelect(file) {
if (!file) return;
// 检查文件类型
if (!file.type.startsWith('image/')) {
alert('请选择图片文件');
return;
}
// 检查文件大小(限制10MB)
if (file.size > 10 * 1024 * 1024) {
alert('图片大小不能超过10MB');
return;
}
try {
// 显示加载状态
this.showLoading('正在压缩图片...');
// 压缩图片
const compressedFile = await this.compressImage(file);
// 显示压缩信息
this.showCompressionInfo(file, compressedFile);
// 上传到服务器
this.showLoading('正在上传...');
const result = await this.uploadToServer(compressedFile);
// 上传成功
this.showSuccess('上传成功!');
return result;
} catch (error) {
this.showError(error.message);
} finally {
this.hideLoading();
}
}
showCompressionInfo(originalFile, compressedFile) {
const originalSize = (originalFile.size / 1024).toFixed(2);
const compressedSize = (compressedFile.size / 1024).toFixed(2);
const ratio = ((compressedFile.size / originalFile.size) * 100).toFixed(1);
console.log(`压缩前: ${originalSize}KB, 压缩后: ${compressedSize}KB, 体积减少: ${100 - ratio}%`);
}
showLoading(message) {
// 实际项目中这里显示加载提示
console.log(message);
}
hideLoading() {
// 隐藏加载提示
}
showSuccess(message) {
// 显示成功提示
console.log(message);
}
showError(message) {
// 显示错误提示
console.error(message);
}
}
// 使用示例
const uploader = new ImageUploader({
maxWidth: 400,
maxHeight: 400,
quality: 0.6
});
// 绑定文件输入
document.getElementById('avatarInput').addEventListener('change', function(e) {
uploader.handleFileSelect(e.target.files[0]);
});compressor.js提供了丰富的配置选项,可以根据不同场景调整:
const options = {
// 压缩质量 (0到1之间)
quality: 0.8,
// 最大宽度
maxWidth: 1920,
// 最大高度
maxHeight: 1080,
// 宽度(设置后会覆盖maxWidth)
width: 800,
// 高度(设置后会覆盖maxHeight)
height: 600,
// 是否保持图片宽高比
strict: true,
// 检查图片方向信息
checkOrientation: true,
// 保留图片的元数据
retainExif: false,
// 文件大小阈值,超过这个大小的PNG图片会转为JPEG
convertSize: 1000000,
// 输出文件类型
mimeType: 'image/jpeg',
// 成功回调
success(result) {
console.log('压缩成功', result);
},
// 错误回调
error(err) {
console.error('压缩失败', err);
}
};class ProductImageProcessor {
constructor() {
this.sizes = [
{ name: 'large', width: 1200, quality: 0.8 },
{ name: 'medium', width: 600, quality: 0.7 },
{ name: 'small', width: 300, quality: 0.6 }
];
}
async processProductImage(file) {
const results = {};
for (const size of this.sizes) {
const compressedFile = await this.compressToSize(file, size);
results[size.name] = compressedFile;
}
return results;
}
compressToSize(file, sizeConfig) {
return new Promise((resolve, reject) => {
new Compressor(file, {
width: sizeConfig.width,
quality: sizeConfig.quality,
mimeType: 'image/jpeg',
success: resolve,
error: reject
});
});
}
}async function processMultipleImages(files) {
const compressedFiles = [];
// 限制并发数量,避免浏览器卡顿
const concurrentLimit = 3;
for (let i = 0; i < files.length; i += concurrentLimit) {
const batch = files.slice(i, i + concurrentLimit);
const promises = batch.map(file =>
new Promise((resolve) => {
new Compressor(file, {
quality: 0.7,
maxWidth: 800,
success: resolve
});
})
);
const batchResults = await Promise.all(promises);
compressedFiles.push(...batchResults);
// 更新进度
updateProgress(i + batch.length, files.length);
}
return compressedFiles;
}
function updateProgress(current, total) {
const percent = Math.round((current / total) * 100);
console.log(`处理进度: ${percent}%`);
}合理设置压缩质量:0.6-0.8的质量通常能在文件大小和图片质量间取得良好平衡
限制图片尺寸:根据实际显示需求设置maxWidth和maxHeight
批量处理控制并发:避免同时处理太多图片导致浏览器卡顿
提供进度反馈:让用户知道处理进度
错误处理:妥善处理压缩失败的情况
虽然compressor.js基于现代浏览器特性,但我们可以添加降级方案:
async function safeCompress(file, options = {}) {
// 检查浏览器是否支持
if (!window.HTMLCanvasElement ||
!HTMLCanvasElement.prototype.toBlob) {
console.warn('浏览器不支持图片压缩,将上传原文件');
return file;
}
try {
return await new Promise((resolve, reject) => {
new Compressor(file, {
quality: options.quality || 0.7,
maxWidth: options.maxWidth || 1920,
maxHeight: options.maxHeight || 1080,
success: resolve,
error: reject
});
});
} catch (error) {
console.error('压缩失败,使用原文件:', error);
return file;
}
}compressor.js是一个实用且强大的前端图片压缩工具。它的主要优势在于:
使用简单:几行代码就能集成
效果明显:通常能减少60%-80%的文件体积
用户体验好:压缩过程对用户透明
节省资源:减少服务器存储和带宽消耗
在实际项目中,建议根据具体业务场景调整压缩参数,并在压缩质量和文件大小之间找到合适的平衡点。对于用户上传的图片,使用compressor.js进行前端压缩,既能提升用户体验,又能降低服务器成本,是一个双赢的选择。
仅供个人学习参考/导航指引使用,具体请以第三方网站说明为准,本站不提供任何专业建议。如果地址失效或描述有误,请联系站长反馈~感谢您的理解与支持!
手机预览