在开发h5图片上传至后端时,会出现图片旋转现象,针对图片旋转的问题,可以通过exif获取图片旋转信息,测试时,虽然ios12.4版本与13.5获取到的orientation都为6表示图片经过旋转,但是两者实际表现不同,13.5系统版本的实际表现是正常未旋转的, 原因:IOS 13.4之前浏览器不会对带 EXIF 信息的图片进行回正,但是自从 iOS 更新到 13.4.1 后,浏览器支持自动回正了 处理方案:判断ios系统版本,13.4之前的版本需要根据exif信息来做旋转更正处理,13.4之后的不做旋转处理
// 判断是否是ios且版本高于13.4
const 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;
};
// 根据信息处理图片旋转
const handleRotate = (file, orientation) => {
if (!file) {
return false;
}
// 判断是否是ios13.4版本以上,orientation为6时是否需要旋转旋转
const ifXz = ifHighThanIos13();
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const { width, height } = file;
if (orientation && ((orientation === 6 && !ifXz) || orientation === 8)) {
canvas.width = height;
canvas.height = width;
} else {
canvas.width = width;
canvas.height = height;
}
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (orientation) {
switch (Number(orientation)) {
case 3: // 需要180度旋转
ctx.rotate((180 * Math.PI) / 180);
ctx.drawImage(file, -width, -height, width, height);
break;
case 6: // 需要顺时针90度旋转更正,但ios版本等于或高于13.4时,获取到旋转信息为6,但实际并未旋转
!ifXz && ctx.rotate((90 * Math.PI) / 180);
!ifXz && ctx.drawImage(file, 0, -height, width, height);
ifXz && ctx.drawImage(file, 0, 0, width, height);
break;
case 8: // 需要逆时针90度旋转更正
ctx.rotate((270 * Math.PI) / 180);
ctx.drawImage(file, -width, 0, width, height);
break;
default:
ctx.drawImage(file, 0, 0, width, height);
break;
}
} else {
ctx.drawImage(file, 0, 0, width, height);
}
return canvas.toDataURL('image/jpeg');
};
/**
* @Description: 处理传入的图片文件
* @param {file} file 上传的图片,jpg格式
* @param {String} name 文件名字
* @param {function} callback 回调函数
*/
const handleImage = (file, name, callback) => {
// const that = this;
if (!file || !window.FileReader) return;
let orientation = null; // 图片旋转信息
EXIF.getData(file, function a() {
orientation = EXIF.getTag(this, 'Orientation');
const reader = new FileReader();
reader.onload = function b() {
const img = new Image();
img.src = this.result;
img.onload = function c() {
const data = handleRotate(img, orientation);
if (data) {
const fileData = dataURLtoFile(data, name); // 处理成自己想要的文件格式
callback && callback(fileData, file);
}
};
};
reader.readAsDataURL(file.file);
});
};