实现思路
通过调整图片的分辨率
或者绘图质量
来达到图片压缩的效果:
获取上传 Input 中的图片对象 File
将图片转换成 base64 格式
base64 编码的图片通过 Canvas 转换压缩,这里会用到的 Canvas 的 drawImage 以及 toDataURL 这两个 Api,一个调节图片的分辨率的,一个是调节图片压缩质量并且输出的
转换后的图片生成对应的新图片,然后输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
export const compressImage = (file, maxSize = 1024 * 1024 * 0.5) => { if (file.size > maxSize) { canvasDataURL(file, (blob) => { console.log('压缩前:' + file.size / 1024 / 1024 + 'M') console.log('压缩后:' + blob.size / 1024 / 1024 + 'M') const compresFile = new File([blob], file.name, { type: 'image/jpeg', }) return compresFile }) } else { return file } }
|
注意:最大文件大小设置过小可能导致无限循环(个人建议为 300kb 以上,最好增加最大循环次数)
通过 canvas 画布实现压缩,并转化为 base64 格式的图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
function canvasDataURL(file, callback) { const reader = new FileReader() reader.readAsDataURL(file) reader.onload = function () { const img = new Image() const canvas = document.createElement('canvas') const drawer = canvas.getContext('2d') img.src = this.result img.onload = function () { const quality = 0.5
convertBase64UrlToBlob(canvas.toDataURL('image/jpeg', quality), callback) } } }
|
将 base64 格式转化为 Blob 格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
function convertBase64UrlToBlob(urlData, callback) { const arr = urlData.split(',') const mime = arr[0].match(/:(.*?);/)[1] const bstr = atob(arr[1]) let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } callback( new Blob([u8arr], { type: mime, }) ) }
|
相关插件
引用站外地址
compressor.js 官方文档
使用canvas做压缩工作的图像压缩器
安装compression.js
1
| npm install compressorjs
|
引入
1
| import Compressor from 'compressorjs'
|
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| document.getElementById('file').addEventListener('change', (e) => { const file = e.target.files[0] if (!file) { return } new Compressor(file, { quality: 0.6, success(result) { const formData = new FormData() formData.append('file', result, result.name) axios.post('/path/to/upload', formData).then(() => { console.log('Upload success') }) }, error(err) { console.log(err.message) }, }) })
|