公司项目中总结的一点经验,给有遇到类似问题的小伙伴提供一下思路。水平浅,代码不规整的地方,望轻喷。
部分未解决问题(其他角度拍照无法翻转)
1.手机必须支持重力感应,不然Orientation值是不变的;
2.有部分手机(R11),拍照不含有Orientation值;
node安装 exif-js
npm install exif-js -S
默认浏览器不会对带 EXIF 信息的图片进行回正,之前确实不会。但是自从 iOS 更新到 13.4.1 后,浏览器支持自动回正了。
增加判断浏览器是否支持带EXIF的图片自动回正
文件名 IsAutoRotateImg.js
// 判断浏览器是否支持对图片进行回正操作
// 一张 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 {
// console.log('isImageAutomaticRotation === undefined');
resolve(isImageAutomaticRotation);
}
});
}
处理图片旋转,获取图片的Orientation,根据Orientation的值去旋转图片
import { EXIF } from "exif-js"
//引入判断浏览器是否支持带EXIF的图片自动回正
import { detectImageAutomaticRotation } from "@/common/IsAutoRotateImg.js"
//imgFile 为 文件类型
const _rotateImg = (imgFile) => {
console.log(imgFile);
return new Promise((resolve, reject) => {
EXIF.getData(imgFile, function() {
console.log('进入getdata')
let exifTags = EXIF.getAllTags(this);
let reader = new FileReader();
reader.readAsDataURL(imgFile);
reader.onload = e => {
let imgData = e.target.result;
// 判断浏览器是否支持对图片进行回正操作
detectImageAutomaticRotation().then(res => {
//res为true时。浏览器支持对带 EXIF 信息的图片进行自动回正
if (res) {
return resolve(imgData)
}
//res为false时。执行js,对带 EXIF 信息的图片进行回正
// 8 表示 顺时针转了90
// 3 表示 转了 180
// 6 表示 逆时针转了90
if (
exifTags.Orientation == 8 ||
exifTags.Orientation == 3 ||
exifTags.Orientation == 6
) {
//翻转
//获取原始图片大小
const img = new Image();
img.src = imgData;
img.onload = function() {
let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');
//如果旋转90
if (
exifTags.Orientation == 8 ||
exifTags.Orientation == 6
) {
cvs.width = img.height;
cvs.height = img.width;
} else {
cvs.width = img.width;
cvs.height = img.height;
}
if (exifTags.Orientation == 6) {
//原图逆时针转了90, 所以要顺时针旋转90
ctx.rotate(Math.PI / 180 * 90);
ctx.drawImage(
img,
0,
0,
img.width,
img.height,
0,
-img.height,
img.width,
img.height
);
}
if (exifTags.Orientation == 3) {
//原图逆时针转了180, 所以顺时针旋转180
ctx.rotate(Math.PI / 180 * 180);
ctx.drawImage(
img,
0,
0,
img.width,
img.height,
-img.width,
-img.height,
img.width,
img.height
);
}
if (exifTags.Orientation == 8) {
//原图顺时针旋转了90, 所以要你时针旋转90
ctx.rotate(Math.PI / 180 * -90);
ctx.drawImage(
img,
0,
0,
img.width,
img.height,
-img.width,
0,
img.width,
img.height
);
}
resolve(cvs.toDataURL('image/jpeg'));
}
} else {
resolve(imgData);
}
})
}
});
});
}
export default _rotateImg
参考资料:http://www.zyiz.net/tech/detail-135910.html
https://www.cnblogs.com/jrg-Archer/p/11659910.html