前段时间在上传图片的时候前端使用FileReader将图片读到内存,使用canvas进行压缩,然后上传,在安卓手机上没有问题,但是在iphone的Safari浏览器中一直存在图片方向不正的问题,经过多方面检查才明白,原因可以查看此处:图片方向有误的原因 。
接下来来说解决方案:
首先可以使用GitHub上的exif.js (exif.js的翻译)来读取图片的Orientation
元数据,在根据下面这张图进行方向调整就OK了:
下面主要把代码处理的关键位置展示出来,很多其他限制需要自行解决:
$("#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端还是移动端,都是需要加上面这段代码进行图片翻转的。