文章目录

前段时间在上传图片的时候前端使用FileReader将图片读到内存,使用canvas进行压缩,然后上传,在安卓手机上没有问题,但是在iphone的Safari浏览器中一直存在图片方向不正的问题,经过多方面检查才明白,原因可以查看此处:图片方向有误的原因

接下来来说解决方案:

首先可以使用GitHub上的exif.jsexif.js的翻译)来读取图片的Orientation 元数据,在根据下面这张图进行方向调整就OK了:

Exif方向标记值

下面主要把代码处理的关键位置展示出来,很多其他限制需要自行解决:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
$("#uploaderInput").on("change", function (e) {
var files = e.target.files,
canvasTemp = $("#canvasTemp")[0];

for (var i = 0, len = files.length; i < len; i++) {
var file = files[i];
EXIF.getData(file, function (file) {
var _this = this,
orientation = EXIF.getTag(_this, 'Orientation') ,
reader = new FileReader();
reader.readAsDataURL(_this);
reader.onload = function () {
var imgTemp = new Image();
imgTemp.src = this.result;
imgTemp.onload = function () {
var thisImg = this;
var ctx = canvasTemp.getContext("2d");
var degree = 0,
drawWidth = sWidth, // sWidth图片宽度
canvasWidth = sWidth,
drawHeight = sHeight, // sWidth图片高度
canvasHeight = sHeight;

if (orientation) {
//判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
switch (orientation) {
//iphone横屏拍摄,此时home键在左侧
case 3:
degree = 180;
drawWidth = -sWidth;
drawHeight = -sHeight;
break;
//iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)
case 6:
canvasWidth = sHeight;
canvasHeight = sWidth;
degree = 90;
drawWidth = sWidth;
drawHeight = -sHeight;
break;
//iphone竖屏拍摄,此时home键在上方
case 8:
canvasWidth = sHeight;
canvasHeight = sWidth;
degree = 270;
drawWidth = -sWidth;
drawHeight = sHeight;
break;
}
}

// canvas清屏
ctx.clearRect(0, 0, canvasTemp.width, canvasTemp.height);
// 重置canvas宽高
canvasTemp.width = canvasWidth;
canvasTemp.height = canvasHeight;

//使用canvas旋转校正
ctx.rotate(degree * Math.PI / 180);
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, drawWidth, drawHeight);
ctx.drawImage(thisImg, 0, 0, drawWidth, drawHeight);
// 如果是jpeg/webp图片,可设置图片质量,png图片不能设置质量
var quantity = thisImg.src.length > (1024 * 1024) ? 0.8 : 1.0;
// 导出图片的base64
var dataUrl = canvasTemp.toDataURL('image/jpeg', quantity);

// 在页面中直接用此处导出的base64填充图片的src,并且上传的时候上传base64格式,或者是将base64转成Blob上传

// base64转Blob
// function dataURLtoBlob(base64Data) {
// var parts = base64Data.split(';base64,');
// var contentType = parts[0].split(':')[1];
// var raw = window.atob(parts[1]);
// var rawLength = raw.length;
// var uInt8Array = new Uint8Array(rawLength);
// for (var i = 0; i < rawLength; ++i) {
// uInt8Array[i] = raw.charCodeAt(i);
// }
// return new Blob([uInt8Array], { type: contentType });
// }
}
}
});
}
});

实际上是iphone或者是支持带方向传感器的数码相机拍出来的照片都会带有Orientation 方向元数据,所以不管是在PC端还是移动端,都是需要加上面这段代码进行图片翻转的。

文章目录