iOS13.4+版本h5拍照图片旋转问题的解决方案

问题描述

前几天刚解决完 Safari 上 h5 拍照会旋转 90 度的问题,今天更新完苹果系统后(13.4 ——> 13.6),突然发现图片又旋转了。前几天不刚测完是好的么,怎么又出问题了。拿公司测试机 12.6 版本测试了下发现没毛病,就基本定位到问题所在了:iOS13.4+版本可能都存在此问题。

然后就是打断点调试,发现新系统下图片的 Orientation 仍然为 6 ,但其实照片(竖着拍)已经被苹果自动旋转回来了。然后我的代码中针对 6 的情况向右旋转了 90 度,这才导致图片又旋转回去了:

1
2
switch (Orientation) {
case 6: //需要顺时针(向右)90度旋转

解决方案

判断系统版本

既然是 iOS 系统版本问题,那么最粗暴的方案就是对系统进行判断,如果高于 13.4,就不去旋转。具体封装的方法代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 判断是IOS13.4以上的系统 13.4以上返回true
/**
* @param {Object} file 文件资源
*/
detectImageAutomaticRotation(file) {
let u = navigator.userAgent,
app = navigator.appVersion;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isIOS) {
let ver = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
let ver1 = parseInt(ver[1])
let ver2 = parseInt(ver[2])
if (ver1 >= 13 && ver2 >= 4) {
// if (file.name == 'image.jpg') { //判断是拍照上传的还是相册选取的,IOS拍完照还没有确定的时候,图片的名字统一都是image.jpg
// return true
// }
return true
} else {
return false
}
} else {
return false;
}
},

但这个方案有个小的隐患,就是我们无法预知今后苹果是否会把这个“自我修正”行为改回去,一旦有这种情况,我们还要重新变动代码,略显麻烦。

用一张特殊的图片来检测当前浏览器是否对带 EXIF 信息的图片进行回正

这是网上找到的一种方案,思路就是用一张「 2x1 的 JPEG 且 EXIF Orientation 为 6」的图片来检测当前浏览器是否对带 EXIF 信息的图片进行回正,如果图片变成 1x2,说明浏览器对图片进行了回正。具体代码见下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 用一张特殊的图片来检测当前浏览器是否对带 EXIF 信息的图片进行回正
// 方法来源: https://github.com/blueimp/JavaScript-Load-Image

// 一张 2x1 的 JPEG 图片, EXIF Orientation: 6
const testAutoOrientationImageURL =
'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/x' +
'ABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAA' +
'AAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==';
let isImageAutomaticRotation;

export function detectImageAutomaticRotation() {
return new Promise(resolve => {
if (isImageAutomaticRotation === undefined) {
const img = new Image();

img.onload = () => {
// 如果图片变成 1x2,说明浏览器对图片进行了回正
isImageAutomaticRotation = img.width === 1 && img.height === 2;

resolve(isImageAutomaticRotation);
};

img.src = testAutoOrientationImageURL;
} else {
resolve(isImageAutomaticRotation);
}
});
}

参考链接

关于 iOS 13.4.1 后照片在浏览器中旋转的兼容性处理