背景
在很多业务场景中,经常会让用户拍照上传图片。随着现在的人生活质量越来预高,手机的配置也非常好。这就导致用手机拍出来的照片都是高清的普遍都是M级别以上的。这个时候如果直接上传原图的话,对本身的项目是一种损耗,为了减少不必要的损耗那么我们只能将上传的照片进行压缩。
拍照实现
- 使用原生input调用拍照功能 下面这串代码是只允许调用拍照的,去掉了从相册中选择图片的功能。
<div class="ex-take-picture__content-button ex-take-picture__button">
<label for="fileInpBtn">立即拍照</label>
<input id="fileInpBtn" type="file" capture="camera" style="display: none;" @change="imgup" accept="image/*">
</div>
2 获取拍照的文件信息
这里的preloadAll方法只是一个加载图片对象的方法,其实可以不用的 因为在压缩图片的方法里面已经有加载过了,有优化的空间。
async imgup (e) {
let file = e.target.files[0]
this.localId = window.URL.createObjectURL(file)
this.imgData = await this.compressImg(file) // 压缩图片
// 这里是加载图片
preloadAll({
links: [this.localId],
type: 'image'
}).then(res => {
const img = res[0].resource
// 根据宽度高度比例设置图片该固定哪个一边 另一边自适应 这样图片不会变形
const percentage = img.width / img.height
if (percentage >= 1) {
// 横屏
this.previewImgStyle = {
backgroundImage: `url('${this.localId}')`
}
this.previewImgClass = 'bgYCenter'
} else {
// 竖屏
this.previewImgStyle = {
backgroundImage: `url('${this.localId}')`
}
this.previewImgClass = 'bgXCenter'
}
})
}
压缩图片
加载图片完成后获取图片的原始宽度高度然后固定宽度或者高度,然后等比例缩放这是压缩第一步;如果这样压缩的程度还不够,那么可以再将图片放到canvas里面使用canvas的toBlob或者toDataURL进行第二次压缩。
compressImg (fileObject) {
return new Promise(resolve => {
const MAX_WH = 800
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let img = new Image()
img.src = window.URL.createObjectURL(fileObject)
img.onload = function () {
if (img.height > MAX_WH) {
// 宽度等比例缩放 *=
img.width *= MAX_WH / img.height
img.height = MAX_WH
}
if (img.width > MAX_WH) {
// 宽度等比例缩放 *=
img.height *= MAX_WH / img.width
img.width = MAX_WH
}
canvas.width = img.width
canvas.height = img.height
ctx.clearRect(0, 0, img.width, img.height)
ctx.drawImage(img, 0, 0, img.width, img.height)
// const base64 = canvas.toDataURL('image/jpeg', 0.7)
// newImgList.push(base64)
// if (newImgList.length === 3) resolve(newImgList)
canvas.toBlob(function (blob) {
// const url = URL.createObjectURL(blob)
// const file = new window.File([url], fileObject.name, { type: fileObject.type })
// URL.revokeObjectURL(url)
resolve(blob)
}, 'image/jpeg', 0.7)
}
})
}
其实通过上面的代码实现,我们就有很多可以自己去玩的地方,比如canvas将图片转换成各种文件流或者文件格式的功能。