有些时候在web端上传图片会遇到这种情况,正向的图片,上传预览时就被旋转了。
发生这种情况是因为,照片中包含很多属性来记录拍摄信息。
想要读取这些属性,需要引入EXIF(可在npm上搜索exif-js下载)
EXIF中,包含一个Orientation参数,用来记录拍摄照片时的方向。在使用PS或者其他软件旋转图片时,图片旋转了,但Orientation不会改变,由于我们使用的图片预览器能够预处理图片,使其看起来与旋转后一致,但上传图片时,浏览器并不会预处理。所以导致图片旋转。
要解决这个问题,必须理解Orientation的含义,它一共含有8个值,分别是:1、2、3、4、5、6、7、8。
这8个值对应的意思是:
| Orientation | 释义 |
|-- |-- |
| 1 | 正常 |
| 2 | 正常镜像 |
| 3 | 顺时针旋转180° |
| 4 | 顺时针旋转180°镜像 |
| 5 | 顺时针旋转270°镜像 |
| 6 | 顺时针旋转270° |
| 7 | 顺时针旋转90°镜像 |
| 8 | 顺时针旋转90° |
//代码层面,引入exif-js后,可获取到照片的Orientation值。
//再根据Orientation来判断如何旋转照片。
//以下是示例
EXIF.getData(file, function () {
var Orientation = EXIF.getTag(this, "Orientation");
console.log("Orientation>>>>>>", Orientation);
//转换成base64
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = e => {
if (Orientation == 1) {
console.log("图片无需处理");
} else {
var uploadBase64 = new Image();
uploadBase64.src = e.target.result;
uploadBase64.onload = function () {
//修正旋转图片
var expectWidth = uploadBase64.width;
var expectHeight = uploadBase64.height;
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.width = expectWidth;
canvas.height = expectHeight;
ctx.drawImage(uploadBase64, 0, 0, expectWidth, expectHeight);
var base64 = null;
if (Orientation !== "" && Orientation != 1) {
switch (Orientation) {
case 6:
console.log("顺时针旋转270度");
rotateImg(uploadBase64, "left", canvas);
break;
case 8:
console.log("顺时针旋转90度");
rotateImg(uploadBase64, "right", canvas);
break;
case 3:
console.log("顺时针旋转180度");
rotateImg(uploadBase64, "horizen", canvas);
break;
}
//输出转换后的base64图片
var base64 = canvas.toDataURL(file.type, 1);
//输出转换后的流
var newBlob = _this.convertBase64UrlToBlob(base64, file.type);
}
};
}
};
})
//对图片旋转处理
rotateImg(img, direction, canvas) {
console.log("开始旋转图片");
//图片旋转4次后回到原方向
if (img == null) return;
var height = img.height;
var width = img.width;
var step = 2;
if (direction == "right") {
step++;
} else if (direction == "left") {
step--;
} else if (direction == "horizen") {
step = 2; //不处理
}
//旋转角度以弧度值为参数
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;
}
console.log("结束旋转图片");
}