注:1.此方法将上传的图片等比例压缩或放大至500kb左右。
2.上传非正照,如人脸照片,强制旋转为正照。
3.iOS 13.3.1以上版本手机拍出来的照片,视觉上是正照,实际顺时针旋转了90度,通过判断版本号,强制逆时针旋转90度回正后再上传。
1.在公共js,如common.js里封装:
/*图片旋转处理*/
export function rotateImg(img, direction, canvas) {
var min_step = 0;
var max_step = 3;
if (img == null) return;
var height = img.height;
var width = img.width;
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
//解决iOS版本13.3.1以上图片旋转问题
var str= navigator.userAgent.toLowerCase();
var ver=str.match(/cpu iphone os (.*?) like mac os/);
if((ver && ver[1].replace(/_/g,".").slice(0,2)==13 && ver[1].replace(/_/g,".").slice(3,4)>3) || ( ver && ver[1].replace(/_/g,".").slice(0,2)>=14) ){
step = 0;
}
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
/*base64转blob*/
export function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime
});
}
2.组件中使用:
<template>
<input type="file" accept="image/*" @change="uploadImg($event)">
</template>
import { rotateImg, dataURLtoBlob } from "@/utils/common";
methods: {
uploadImg(e) {
if (!e.target.files.length) {
return
}
if (e.target.files[0].type.indexOf('image') < 0) {
Toast({
message: '请选择图片上传',
duration: 1500
});
return
}
let img = new Image();
let _this = this;
_this.Orientation = '';
Exif.getData(e.target.files[0], function () {
_this.Orientation = Exif.getTag(this, "Orientation");
});
let canvas = document.createElement('canvas');
let cxt = canvas.getContext('2d');
let windowURL = window.URL || window.webkitURL;
img.src = windowURL.createObjectURL(e.target.files[0]);
_this.uploading = true;
//图片缩放
img.onload = function () {
let width = 1000;
let height = img.naturalHeight / (img.naturalWidth / 1000);
if (img.naturalWidth > img.naturalHeight) {
width = img.naturalWidth / (img.naturalHeight / 1000);
height = 1000;
} else {
width = 1000;
height = img.naturalHeight / (img.naturalWidth / 1000);
}
canvas.width = width;
canvas.height = height;
cxt.drawImage(this, 0, 0, width, height);
//图片旋转
if (_this.Orientation != "" && _this.Orientation != 1) {
switch (_this.Orientation) {
case 6: //需要顺时针(向左)90度旋转
_this.rotateImg(this, "left", canvas);
break;
case 8: //需要逆时针(向右)90度旋转
_this.rotateImg(this, "right", canvas);
break;
case 3: //需要180度旋转
_this.rotateImg(this, "right2", canvas);
break;
}
}
_this.Orientation = ''
//生成图片
_this.PhotoBase64 = canvas.toDataURL('image/jpeg'); //转base64
let fileObj = _this.dataURLtoBlob(_this.PhotoBase64); //把压缩的base64转化为对象
let formData = new FormData();
formData.append('file', fileObj);
uploadImage(formData).then(res => {
_this.uploading = false;
Toast({
message: '上传成功',
duration: 1500
});
}).catch(e => {
_this.uploading = false;
Toast({
message: '上传失败',
duration: 1500
});
})
}
},
}