10

有些时候在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("结束旋转图片");
}

这样就可以解决,web端上传图片时,图片被旋转的问题啦。


Layla
56 声望5 粉丝

Life is tough.