引入exif-js
场景:在使用vant-ui组件上传图片时,iphone手机竖屏拍的照片上传时会向左旋转90度
获取拍摄方向
EXIF.getData(file, function () {
const orient = EXIF.getTag(this, 'Orientation')
resolve(orient)
})
orient为6时 iphone为竖屏拍照 使用canvas校正旋转方向
rotateImage: (image, width, height) => {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
ctx.save()
console.warn(width,height);
canvas.width = width
canvas.height = height
ctx.rotate(0 * Math.PI / 180)
ctx.drawImage(image, 0, 0, width, height)
ctx.restore()
return canvas.toDataURL("image/jpeg")
},
ios13以上的版本才会出现这个问题,判断ios版本
ifHighThanIos13: () => {
const userAgent = navigator.userAgent.toLowerCase();
const ios = userAgent.match(/cpu iphone os (.*?) like mac os/);
if (!ios) {
return false;
}
const iosVersion = ios[1].replace(/_/g, '.'); // 获取ios版本
const iosV1 = iosVersion.split('.')[0]; // 大版本号
const iosV2 = iosVersion.split('.')[1]; // 小版本号
if (Number(iosV1) < 13 || (Number(iosV1) === 13 && Number(iosV2) < 4)) {
return false;
}
if (Number(iosV1) > 13 || (Number(iosV1) === 13 && Number(iosV2) >= 4)) {
return true;
}
return false;
}
总结
在utils中引入index.js文件
import EXIF from 'exif-js'
export default {
getOrientation: (file) => {
return new Promise((resolve) => {
EXIF.getData(file, function () {
const orient = EXIF.getTag(this, 'Orientation')
resolve(orient)
})
})
},
dataURLtoFile: (dataurl, filename) => {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const 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 });
},
rotateImage: (image, width, height) => {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
ctx.save()
console.warn(width,height);
canvas.width = width
canvas.height = height
ctx.rotate(0 * Math.PI / 180)
ctx.drawImage(image, 0, 0, width, height)
ctx.restore()
return canvas.toDataURL("image/jpeg")
},
ifHighThanIos13: () => {
const userAgent = navigator.userAgent.toLowerCase();
const ios = userAgent.match(/cpu iphone os (.*?) like mac os/);
if (!ios) {
return false;
}
const iosVersion = ios[1].replace(/_/g, '.'); // 获取ios版本
const iosV1 = iosVersion.split('.')[0]; // 大版本号
const iosV2 = iosVersion.split('.')[1]; // 小版本号
if (Number(iosV1) < 13 || (Number(iosV1) === 13 && Number(iosV2) < 4)) {
return false;
}
if (Number(iosV1) > 13 || (Number(iosV1) === 13 && Number(iosV2) >= 4)) {
return true;
}
return false;
}
}
在需要调用的文件中引用
import fileUtils from "./index.js";
在van-upload的before-Read中使用
beforeRead(file) {
return new Promise((resolve, reject) => {
fileUtils.getOrientation(file).then(orient => {
if (orient && orient === 6 && fileUtils.ifHighThanIos13()) {
let reader = new FileReader();
let img = new Image();
reader.onload = e => {
img.src = e.target.result;
img.onload = function() {
const data = fileUtils.rotateImage(img, img.width, img.height);
const newFile = fileUtils.dataURLtoFile(data, file.name);
resolve(newFile);
};
};
reader.readAsDataURL(file);
} else {
resolve(file);
}
});
});
},