惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

逐梦个人博客

使用原生JS监听浏览器的前进后退事件-逐梦个人博客 微信小程序中使用微信头像的实现方式-逐梦个人博客 如何在WebWorker中使用psd.js-逐梦个人博客 如何根据权重裁剪FaceApi.js返回的人脸数据-逐梦个人博客 在WebWorker中使用FaceAPI.js的正确姿势-逐梦个人博客 解锁React组件函数this绑定新方式-逐梦个人博客 React通用带上下文的组件ID实现方案-逐梦个人博客 防止其他网站通过iframe嵌套自己站点的两种方式-逐梦个人博客 警惕!wordpress站长必知的重大安全漏洞合集-逐梦个人博客
关于照片Exif Orientation信息的处理-逐梦个人博客
Dean · 2023-06-09 · via 逐梦个人博客

在展示照片尤其是手机拍摄的照片时,可能会遇到这么一个奇怪的现象,明明看到的图片是横的,但在部分浏览器中打开可能是竖的,导致这个问题的原因就是照片中存储的exif信息在作祟,有的浏览器矫正了exif中存储的旋转角度,有的浏览器则没有,就会导致我们看到的图片不一致。

一、什么是exif

Exif(可交换图像文件格式)是一种协议,用于存储有关数码相机拍摄的图像的各种元信息。Exif与实际图像数据一起存储。Exif中的一些元信息包括相机制造商,快门速度,焦距,方向,拍摄时间等。这些元信息称为标签,每个标签都有一个由Exif格式标准决定的特定标签号。标签的完整列表可参考:https://exiv2.org/tags.html

二、exif中的旋转角度orientation

上面我们提到了exif中存储了一些图像元信息,其中就包括了旋转方向Orientation,常用的Orientation主要有8类,按照编号1-8含义如下表:

Orientation值含义
1旋转0°
2水平翻转
3顺时针旋转180°
4垂直翻转
5顺时针旋转90°+水平翻转
6顺时针旋转90°
7顺时针旋转90°+垂直翻转
8逆时针旋转90°

借用网络上比较流行的一张图,8个方向的图示如下:

三、使用canvas矫正照片旋转角度

在知道了Orientation值分别对应的含义后,我们需要矫正旋转角度让照片在所有的浏览器下保持一致,一般的做法是在上传图片时由后端解析出照片中的旋转角度并记录,然后抹除旋转角度存储到服务器,然后将储存的图片和解析出的角度传递给前端,前端可以利用canvas来矫正图片的旋转角度,代码如下:

function getOrientationAppliedImage(src, imgOrientation) {
  return new Promise((resolve, reject) => {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    loadImg(src).then((img) => {
      const { width, height } = img;
      const halfWidth = width / 2;
      const halfHeight = height / 2;
      canvas.width = width;
      canvas.height = height;

      const transform = (func, isSwitch = false) => {
        if (isSwitch) {
          canvas.width = height;
          canvas.height = width;
        }
        ctx.translate(canvas.width / 2, canvas.height / 2);
        func && func();
        ctx.drawImage(img, -halfWidth, -halfHeight);
      };

      switch (imgOrientation) {
        case 2:
          transform(() => {
            ctx.scale(-1, 1);
          });
          break;
        case 3:
          transform(() => {
            ctx.rotate(Math.PI);
          });
          break;
        case 4:
          transform(() => {
            ctx.scale(1, -1);
          });
          break;
        case 5:
          transform(() => {
            ctx.scale(-1, 1);
            ctx.rotate(Math.PI / 2);
          }, true);
          break;
        case 6:
          transform(() => {
            ctx.rotate(-Math.PI / 2);
          }, true);
          break;
        case 7:
          transform(() => {
            ctx.scale(1, -1);
            ctx.rotate(Math.PI / 2);
          }, true);
          break;
        case 8:
          transform(() => {
            ctx.rotate(Math.PI / 2);
          }, true);
          break;
        default:
          ctx.drawImage(img, 0, 0);
          break;
      }

      resolve(canvas.toDataURL());
    }).catch(err => reject);
  });
}

调用getOrientationAppliedImage方法并传入图片链接和解析得到的旋转角度即可得到校正后的图片。

四、写在最后

当然我们也可以选择在上传图片的时候由后端直接抹除并矫正图片的旋转角度,但是直接改原图是不是合理还是有待考量的。