记一次用canvas解决图片压缩
vant-ui upload组件 上传图片自动翻转了
在我们使用 vant-UI的uploader 组件时。
uploader 组件在某些安卓机中出现 :
上传时正着显示的图片,上传之后图片自动90°旋转了。
因此我们需要使用 Exif 插件对图片的信息进行分析。
npm install exif-js --save
import Exif from 'exif-js'
const getOrientation = (file) => {
return new Promise((resolve) => {
let Orientation = null
// 去获取拍照时的信息 ,解决拍出来的照片旋转问题
Exif.getData(file, () => {
Orientation = Exif.getTag(file, 'Orientation')
resolve(Orientation)
})
})
}
图片压缩
图片压缩的思路就是使用canvas的drawImage
将原来较大的图片绘制到新的画布上并且设置大小。
最后将canvas图片通过toBlob方法转化成Bolb , 再使用 window.File()
将Bolb文件转化为真正的File文件。
canvas.toBlob
方法接收3个参数,回调,name, 和压缩比例。因为我们这里是手机端,
我们这里已经对图片的像素大小进行了修改 ,在压缩比例上我们不做太大修改。
以下是整个方法的代码。
// 压缩图片 纠正图片
const passFile = (file, base64) => {
return new Promise((resolve, reject) => {
let img = new Image
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
img.onload = async function () {
let type = file.type.split('image/')[1],
name = file.name,
size = file.size
// 图怕大小小于1.2Mb原路返回文件
if (size < 1.2 * 1024 * 1024) {
resolve(file)
canvas = null
return
}
// 版本1 为了解决 压缩越来越大 我们固定宽度进行压缩
// 我们调节比例 在1.2mb以下时我们不压缩 当前大于1.2MB时 ,按宽度 700像素压缩得到
// 一个合适的比例 :这个比例来自于手机拍照
let w = 750
let h = img.height * 750 / img.width
const getOrientation = (file) => {
return new Promise((resolve) => {
let Orientation = null
// 去获取拍照时的信息 ,解决拍出来的照片旋转问题
Exif.getData(file, () => {
Orientation = Exif.getTag(file, 'Orientation')
resolve(Orientation)
})
})
}
let Orientation = await getOrientation(file)
// 所有图都处理成 宽小长高的图片
if (Orientation && Orientation !== 1) {
switch (Orientation) {
case 6:
canvas.width = h
canvas.height = w
ctx.rotate(Math.PI / 2)
ctx.drawImage(img, 0, -h, w, h)
break
case 3:
canvas.width = w
canvas.height = h
ctx.rotate(Math.PI)
ctx.drawImage(img, -w, -h, w, h)
break
case 8:
canvas.width = h
canvas.height = w
ctx.rotate(3 * Math.PI / 2)
ctx.drawImage(img, -w, 0, w, h)
break
}
} else {
ctx.drawImage(img, 0, 0, w, h)
}
// 压缩优化
canvas.toBlob(function (res) {
const Blob2ImageFileForWXBrowser = (obj) => new window.File([obj], `${(new Date).getTime()}.${type}`);
resolve(Blob2ImageFileForWXBrowser(res))
canvas = null
}, name, 0.9)
}
img.src = base64
})
}