问题:在做钉钉微应用的时候上传人脸照片时图片发生的旋转,在ios机上没有任何问题,部分安卓机拍照好处有一个自动旋转的过程。
首先我们借助exif-js可以实现相机镜头的读取,不支持IE10以下,可以直接引用的js文件,也可以使用npm安装依赖
npm install exif-js --save
import EXIFfrom 'exif-js';
或
/index.html引入js
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
这个js文件暴露了一个EXIF的全局变量,我们可以把它挂在window对象上,使他变为一个全局变量
<script type="text/javascript">
window.onload = function () {
window.EXIF = EXIF
}
</script>
在上传的file文件中获取相机方向,然后使用convas重绘图片并旋转角度就可以了,我再项目里面使用的是vant-ui
//html
<van-uploader
:after-read="afterRead"
@oversize="onOversize"
:max-size="2048 * 1024"
/>
afterRead: async function(file) {
if (!Array.isArray(file)) {
if (file.file.type.indexOf("image") == -1) {
this.$toast("只能上传图片");
this.vacate.face = "";
} else {
if (file.file.size > 10485760) {
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
let img = new Image();
img.src = file.content; // 指定图片的DataURL(base64编码数据)
img.onload = () => {
canvas.width = 400; // 指定canvas画布大小,该大小为最后生成图片的大小
canvas.height = 300;
context.drawImage(img, 0, 0, 400, 300);
file.content = canvas.toDataURL(file.file.type, 0.92);// 0.92为默认压缩质量
let files = this.dataURLtoFile(file.content, file.file.name);
this.uploadImg(files);
};
}
} else {
this.$toast("不能上传两张图片");
}
}
dataURLtoFile(dataurl, filename) {
// 将base64转换为文件
let arr = dataurl.split(",");
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
},
uploadImg(file) {
let _this = this;
EXIF.getData(file, () => {
let orientation = null; // 相机方向
let imgWidth = null; // 图片宽度
let imgHeight = null; // 图片高度
EXIF.getAllTags(file);
orientation = EXIF.getTag(file, "Orientation");
imgWidth = EXIF.getTag(file, "ImageWidth");
imgHeight = EXIF.getTag(file, "ImageHeight");
if (orientation === 6) {
// 等于6顺时针旋转90度,等于8需要逆时针旋转90度,等于3需要旋转180度
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
let img = new Image();
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = e => {
img.src = e.target.result;
img.onload = () => {
canvas.width = imgWidth;
canvas.height = imgHeight;
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate((90 * Math.PI) / 180); // 旋转角度
context.drawImage(
img,
-(canvas.height / 2),
-(canvas.width / 2),
canvas.height,
canvas.width
);
context.restore(); // 恢复状态
let newImg = canvas.toDataURL("image/jpeg", 1);
let files = _this.dataURLtoFile(newImg, file.name); // 将base64转为files文件
let urlImg = window.URL.createObjectURL(files); // 将file转为临时url给组件回显
this.$set(this.fileList, 0, { url: urlImg, isImage: true });
this.uploadImgAPI(files);
};
};
} else {
// 不需要旋转的直接上传
this.uploadImgAPI(file);
}
});
},
//上传图片
async uploadImgAPI(file) {
const fd = new FormData();
fd.append("file", file);
let res = await this.$store.dispatch("loadUploadPicture", fd);
if (res.code == 200) {
this.$toast("上传成功");
}
},