html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题;Android手机没这个问题。
因此解决这个问题的思路是:获取到照片拍摄的方向角,对非横拍的ios照片进行角度旋转修正。
注:在开发时发现 三星手机提交时会向右旋转90度 所以对仅对安卓系统中三星手机进行特别处理
这里主要用到Orientation属性。说明如下:
旋转角度 | 参数 |
---|---|
0° | 1 |
顺时针90° | 6 |
逆时针90° | 8 |
180° | 3 |
一、html文件
<a href="javascript:document.getElementById('fileobj').click()">
<button type="button" class="upload-image-btn" >
<span class="upload-btn-text" v-if="!show_upload_next_button" v-text="Camera / Photo">span>
<span class="upload-btn-text" v-text="Please add the images" v-else>span>
button>
a>
<input type="file" id="fileobj" accept="image/*" style="display:none" @change="fileobj_change">
二、js文件
fileobj_change: function(e) {
var vue_this = this;
var file = e.target.files[0];
vue_this.show_loading = true;
var orientation = 0;
EXIF.getData(file, function() {
EXIF.getAllTags(this);
orientation = EXIF.getTag(this, 'Orientation');
});
// console.log(orientation)
var reader = new FileReader();
reader.onload = function(readerEvent) {
var face_image = new Image();
face_image.onload = function(imageEvent) {
var canvas = document.getElementById('sketchpad');
drawPhotoImage(this, canvas, face_image, orientation);
vue_this.image_url = canvas.toDataURL('image/jpeg');
vue_this.show_upload_next_button = true;
vue_this.show_loading = false;
};
face_image.src = readerEvent.target.result;
};
reader.readAsDataURL(file);
}
function drawPhotoImage(image, canvas, face_image, orientation) {
var max_size = 544,
width = face_image.width,
height = face_image.height;
if (width > height) {
if (width > max_size) {
height *= max_size / width;
width = max_size;
}
} else {
if (height > max_size) {
width *= max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
if (navigator.userAgent.match(/iphone/i)) {
if (orientation != "" && orientation != 1) {
switch (orientation) {
case 6:
rotateImg(image, 'left', canvas, width, height);
break;
case 8:
rotateImg(image, 'right', canvas, width, height);
break;
case 3:
/*
//原资料中旋转180度方法为调用两遍90度 但是我这边不起作用 所以增加一种新的方式 => right2
rotateImg(image, 'right', canvas, width, height);
rotateImg(image, 'right', canvas, width, height);*/
rotateImg(image, 'right2', canvas, width, height);
break;
default:
canvas.getContext('2d').drawImage(face_image, 0, 0, width, height);
break;
}
} else {
canvas.getContext('2d').drawImage(face_image, 0, 0, width, height);
}
}else if(get_ua_info()){
rotateImg(image, 'left', canvas, width, height);
}else {
canvas.getContext('2d').drawImage(face_image, 0, 0, width, height);
}
}
function rotateImg(img, direction, canvas, width, height) {
var min_step = 0;
var max_step = 3;
if (img == null) {
return;
}
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
step > max_step && (step = min_step);
}else if(direction == 'right2'){
step = 2;
}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, width, height);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height, width, height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height, width, height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0, width, height);
break;
}
}
//判断是否为三星手机
//注:此方法准确率欠佳 若有需求可参考https://github.com/fex-team/ua-device
function get_ua_info(){
if(navigator.userAgent.indexOf(" SM-")!=-1)
return true;
else
return false;
}
github:
https://github.com/exif-js/exif-js