利用exif.js插件解决ios手机上传竖拍照片旋转90度问题
移动端手机拍照时,发现ios手机上传竖拍图片会逆时针旋转90度,横拍照片无此问题,部分安卓手机存在此问题。

解决思路:
获取到照片拍摄的方向角,对非横排的ios照片进行角度旋转修正。 我们可以通过exif.js这个插件获取到它的拍照方向Orientation属性,然后把所有的旋转了的图片都给正过来。
exif.js介绍:
Exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向、相机设备型号、拍摄时间、ISO 感光度、GPS 地理位置等数据。 EXIF 数据主要来自拍摄的照片,多用于移动端开发,PC 端也会用到,此插件兼容主流浏览器,IE10 以下不支持。 exif.js详解,内有github地址
Orientation属性:
旋转角度 | 参数 |
---|
0° | 1 | 顺时针90° | 6 | 180° | 3 | 逆时针90° | 8 |
exif.jsAPI  代码片段:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script>
function selectFileImage(fileObj) {
var file = fileObj.files['0'];
var Orientation = null;
if (file) {
console.log("正在上传,请稍后...");
var rFilter = /^(image\/jpeg|image\/png)$/i;
if (!rFilter.test(file.type)) {
return;
}
EXIF.getData(file, function() {
EXIF.getAllTags(this);
Orientation = EXIF.getTag(this, 'Orientation');
});
var oReader = new FileReader();
oReader.onload = function(e) {
var img= new Image();
img.src = e.target.result;
img.onload = function() {
var expectWidth = this.naturalWidth;
var expectHeight = this.naturalHeight;
if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
expectWidth = 800;
expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
} else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
expectHeight = 1200;
expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = expectWidth;
canvas.height = expectHeight;
ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
var dataUrl= null;
if (navigator.userAgent.match(/iphone/i)) {
console.log('iphone');
if(Orientation != "" && Orientation != 1){
console.log('旋转处理');
switch(Orientation){
case 6://需要顺时针(向左)90度旋转
console.log('需要顺时针(向左)90度旋转');
rotateImg(this,'left',canvas);
break;
case 8://需要逆时针(向右)90度旋转
console.log('需要顺时针(向右)90度旋转');
rotateImg(this,'right',canvas);
break;
case 3://需要180度旋转
console.log('需要180度旋转');
rotateImg(this,'right',canvas);
rotateImg(this,'right',canvas);
break;
}
}
dataUrl= canvas.toDataURL("image/jpeg", 0.8);
}else if (navigator.userAgent.match(/Android/i)) {
var encoder = new JPEGEncoder();
dataUrl= encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);
}else{
if(Orientation != "" && Orientation != 1){
switch(Orientation){
case 6://需要顺时针(向左)90度旋转
console.log('需要顺时针(向左)90度旋转');
rotateImg(this,'left',canvas);
break;
case 8://需要逆时针(向右)90度旋转
console.log('需要顺时针(向右)90度旋转');
rotateImg(this,'right',canvas);
break;
case 3://需要180度旋转
console.log('需要180度旋转');
rotateImg(this,'right',canvas);
rotateImg(this,'right',canvas);
break;
}
}
dataUrl= canvas.toDataURL("image/jpeg", 0.8);
}
$("#myImage").attr("src", dataUrl);
};
};
oReader.readAsDataURL(file);
}
}
function rotateImg(img, direction,canvas) {
var min_step = 0;
var max_step = 3;
if (img == null)return;
var height = img.height;
var width = img.width;
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
</script>
|