地址
github:https://github.com/fengyuanchen/compressorjs
演示地址:https://fengyuanchen.github.io/compressorjs/
方法代码
new Compressor(file, {quality: 0.4, // 压缩等级success(result) {console.log((result.size / 1024 / 1024).toFixed(4), '压缩后大小');},error(err) {console.log(err, '压缩错误');},});
react 示例
演示

代码
index.js
import React, { useState, useEffect } from 'react';import { Upload, message, Radio } from 'antd';import { InboxOutlined } from '@ant-design/icons';import Compressor from 'compressorjs';import styles from './index.less';const { Dragger } = Upload;const options = [{ label: '0.2', value: 0.2 },{ label: '0.4', value: 0.4 },{ label: '0.6', value: 0.6 },{ label: '0.8', value: 0.8 },];const ImgCompressor = () => {const [quality, setQuality] = useState(0.8);const [fileData, setFileData] = useState({ size: 0, url: '', file: null });const [compressorData, setCompressorData] = useState({ size: 0, url: '', file: null });const setData = (file, compre) => {setFileData(file);setCompressorData(compre);};// file/blob 转换为 urlconst transformUrl = file => {let url = '';if (window.createObjectURL != undefined) { // basicurl = window.createObjectURL(file);} else if (window.URL != undefined) { // mozilla(firefox)url = window.URL.createObjectURL(file);} else if (window.webkitURL != undefined) { // webkit or chromeurl = window.webkitURL.createObjectURL(file);}return url;}// 压缩图片const compressorFn = file => {return new Promise(resolve => {const fileData = { // 压缩前文件size: (file.size / 1024 / 1024).toFixed(4),url: transformUrl(file),file,};new Compressor(file, {quality,success(result) {const compressorData = { // 压缩后文件size: (result.size / 1024 / 1024).toFixed(4),url: transformUrl(result),file: result,};fileData.size === compressorData.size && message.info('所选压缩质量等级过小或图片大小过小,无需压缩');setData(fileData, compressorData);resolve(result);},error(err) {// 压缩报错的话 返回原图片message.info(`压缩失败,原图上传!${err}。`);setData(fileData, fileData);resolve(file);},});});}// 压缩等级更新后重新压缩useEffect(() => {fileData.file && compressorFn(fileData.file)}, [quality]);// 上传组件 propsconst props = {name: 'file',accept: 'image/*',multiple: true,action: 'https://172.16.59.21/upload',fileList: [],transformFile(file) { // 上传前转换文件return compressorFn(file);},// onChange(info) { // 虽然使用了 transformFile 方法转换了文件并上传,但是此位置仍然是返回原始文件// const { status } = info.file;// if (status === 'uploading') {// // console.log(info.file, info.fileList, 'uploading');// }// if (status === 'done') {// message.success(`${info.file.name} 上传成功`);// } else if (status === 'error') {// message.error(`${info.file.name} 上传失败`);// console.log(info, info.fileList, '上传失败');// }// },};return (<div className={styles['compressor']}><div className={styles['proportion']}>选择压缩等级:<Radio.Groupoptions={options}onChange={e => setQuality(e.target.value)}value={quality}optionType="button"/></div><Dragger {...props}><p className="ant-upload-drag-icon"><InboxOutlined /></p><p className="ant-upload-text">点击或拖拽文件到此区域上传</p><p className="ant-upload-hint">支持单个或多个上传</p></Dragger><div className={styles['img-list']}><div><div className={styles['img-list-header']}><span>压缩前大小:{fileData.size}M</span></div>{fileData.url && <img src={fileData.url} alt="加载失败" />}</div><div><div className={styles['img-list-header']}><span>压缩后大小:{compressorData.size}M</span>{!!fileData.size && <span>节省空间:{`${((fileData.size - compressorData.size) / fileData.size * 100).toFixed(2)}%`}</span>}</div>{compressorData.url && <img src={compressorData.url} alt="加载失败" />}</div></div></div>);};export default ImgCompressor;
index.less
.compressor {.proportion {margin-bottom: 20px;}.img-list {display: flex;justify-content: space-around;margin-top: 30px;font-size: 16px;> div {width: 330px;height: 500px;img {max-width: 100%;max-height: 100%;}}.img-list-header {> span {margin-right: 24px;}}}}
