上传时,图片发生了自动旋转/翻转,与本地显示的图片方向不一致。实际上,部分 jpg 图片属于 EXIF (可交换的图像文件格式)。EXIF 中包含一个 Orientation 参数,用来记录拍摄照片时的方向。在使用PS或者其他软件旋转图片时,图片旋转了,但 Orientation 不会改变,由于我们使用的图片预览器能够预处理图片,使其看起来与旋转后一致,但上传图片时,浏览器并不会预处理,所以导致图片旋转/翻转。这样的图片在经过 微信、QQ 等软件发送后,图像的 EXIF 信息消失,再次上传时,也不会发生旋转/翻转。

01

EXIF 介绍

1、获取 EXIF 中 Orientation 参数

    * 手写算法获取 Orientation

    * 引入 exif-js 插件获取 Orientation

2、Orientation 参数说明

Orientation 

说明

1

正常 

2

正常镜像

3

顺时针旋转180°

4

顺时针旋转180°镜像

5

顺时针旋转270°镜像

6

顺时针旋转270°

7

顺时针旋转90°镜像

8

顺时针旋转90°

3、以下说明采用方式

    为了方便,采用了第三方插件的形式,移入 [exif-js](https://github.com/exif-js/exif-js) 来获取 Orientation 参数。

* 安装 exif-js

yarn add exif-js

* 引入并获取 Orientation

import EXIF from 'exif-js';let reader = new FileReader();let img = new Image();reader.readAsDataURL(file);reader.onload = function(e) {    img.src = e.target.result;};img.onload = function() {    let orientation;    EXIF.getData(img, function() {        orientation = EXIF.getTag(this, 'Orientation');    });    console.log('orientation:', orientation);}

* 判断并做矫正

    Orientation 有 8 个值,分别代表不同含义,对应需要矫正的方式也不同:1 6 3 8 对应镜像 2 5 4 7

Orientation 

说明

矫正方式

1

正常 

不做操作

2

正常镜像

水平翻转

3

顺时针旋转180°

逆时针旋转 180、向上、右移动复原位置 

4

顺时针旋转180°镜像

水平翻转、逆时针旋转 90、向上、右移动复原位置

5

顺时针旋转270°镜像

垂直翻转、顺时针旋转 90、向上平移复原位置

6

顺时针旋转270°

顺时针旋转 90、向上平移复原位置

7

顺时针旋转90°镜像

垂直翻转、逆时针旋转 90、向右平移复原位置

8

顺时针旋转90°

逆时针旋转 90、向右平移复原位置

* 主要代码展示

canvas.width = targetWidth;canvas.height = targetHeight;context.clearRect(0, 0, targetWidth, targetHeight); // 清除画布// 1 6 3 8 对应镜像 2 5 4 7if (orientation === 3) {    context.rotate(Math.PI); // 逆时针旋转 180    context.translate(-canvas.width, -canvas.height); // 向上、右移动} else if (orientation === 4) {    context.translate(canvas.width / 2, canvas.height / 2);    context.scale(-1, 1); // 水平翻转    context.translate(-canvas.width / 2, -canvas.height / 2);    context.rotate(Math.PI); // 逆时针旋转 180    context.translate(-canvas.width, -canvas.height); // 向上、右移动} else if (orientation === 5) {    canvas.width = targetHeight;    canvas.height = targetWidth;    context.translate(canvas.width / 2, canvas.height / 2);    context.scale(1, -1); // 垂直翻转    context.translate(-canvas.width / 2, -canvas.height / 2);    context.rotate(-Math.PI / 2); // 顺时针旋转 90    context.translate(-canvas.height, 0); // 向上平移} else if (orientation === 6) {    canvas.width = targetHeight;    canvas.height = targetWidth;    context.rotate(-Math.PI / 2); // 顺时针旋转 90    context.translate(-canvas.height, 0); // 向上平移} else if (orientation === 7) {    canvas.width = targetHeight;    canvas.height = targetWidth;    context.translate(canvas.width / 2, canvas.height / 2);    context.scale(1, -1); // 垂直翻转    context.translate(-canvas.width / 2, -canvas.height / 2);    context.rotate(Math.PI / 2); // 逆时针旋转 90    context.translate(0, -canvas.width); // 向右平移} else if (orientation === 8) {    canvas.width = targetHeight;    canvas.height = targetWidth;    context.rotate(Math.PI / 2); // 逆时针旋转 90    context.translate(0, -canvas.width); // 向右平移} else if (orientation === 2) {    context.translate(canvas.width / 2, canvas.height / 2);    context.scale(-1, 1); // 水平翻转    context.translate(-canvas.width / 2, -canvas.height / 2);} else {return resolve(file);}context.drawImage(img, 0, 0, targetWidth, targetHeight);

4、工具尝试

* [在线查看图片信息](http://code.ciaoca.com/javascript/exif-js/demo/upfile)* [在线编辑](https://codepen.io/movii/pen/MJzRYr/)* [图片取材](http://www.peichenhu.cn/%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE/fix-image-orientation.html#%E4%BB%80%E4%B9%88%E6%98%AF%E6%95%B0%E7%A0%81%E7%85%A7%E7%89%87%E6%96%B9%E5%90%91%E9%94%99%E8%AF%AF)

02

巨坑

1、坑

    整个过程耗费了我很长时间(晚上 + 早上),一直在纠结方向旋转、翻转、平移的问题,当我把眼前的 11 个特殊的图片试完之后,我以为成功了,准备交给测试去测一下。结果...

    这种根据参数做自动旋转的方式看是否合理,但实际问题很多:操作系统、浏览器型号、浏览器版本...

    不同操作系统上展示的图片方向不同,如:windows 10/mac 上展示的是旋转之后的图片,而 windows 7 上部分图片展示的是原始图像(未找到规律)

2、以 6 为例

* windows 7 Chrome 65

html5图片旋转后平移 html如何让图片旋转_html怎么让图片旋转

* windows 7 Chrome 83

html5图片旋转后平移 html如何让图片旋转_html图片旋转_02

* windows 7 Firefox 77

html5图片旋转后平移 html如何让图片旋转_html怎么让图片旋转_03

* windows 10 Chrome 65

html5图片旋转后平移 html如何让图片旋转_html5图片旋转后平移_04

* windows 10 Chrome 81 -> 部分图片上传与桌面展示一致,但实际url图片不会正的

html5图片旋转后平移 html如何让图片旋转_html怎么让图片旋转_05

* windows 10 Firefox 75

html5图片旋转后平移 html如何让图片旋转_html怎么让图片旋转_06

* Mac Chrome 83

html5图片旋转后平移 html如何让图片旋转_html图片旋转_07

* windows Chrome 80

html5图片旋转后平移 html如何让图片旋转_python 数据逆时针旋转270度_08

以上内容均为个人总结,如有不对的地方欢迎指正