读取带旋转信息的图片


发布于

|

分类

EXIF信息真好,EXIF信息真烦

工作中经常碰到带有旋转信息的图片,读出来之后整个图片被旋转了,标注信息和图片对不上。之前旋转图片一直是个老大难的问题,后来下定决心给解决掉了。

首先,「正确」的图片是什么样子的?

有几个判断方法:

  1. Mac:在Finder里面直接看图片,看到的样子
  2. Windows:在资源管理器里面直接看图片,看到的样子
  3. 将图片直接拖进Chrome,显示出来的样子

以上方法都是读取EXIF信息并旋转过后的结果,也就是我们希望得到的结果。

如果你喜欢使用OpenCV……

恭喜你!最简单了!

你只要将你的OpenCV升级到3.1以上,并且读图片的时候不要使用IMREAD_UNCHANGED参数就好了。

这里说一下。仔细看下IMREAD_常量的定义,会发现其实这些常量是可以组合的,比如IMREAD_UNCHANGED就是1,IMREAD_IGNOREORIENTATION就是128。既然我们需要让OpenCV自己来处理旋转这个事情,就不能将128这一位给置上。然而IMREAD_UNCHANGED是255,自然就不能用啦。最多可以写127。

如果你喜欢用PIL/Pillow……

不幸的是,你需要自己将EXIF信息找出来,判断旋转方向,并自己进行旋转——不过也不难。

首先我们需要将旋转信息找出来。往上很多方法是再引入一下PIL的EXIF包,我觉得比较麻烦——明明读出来的图片里面就可以直接取到EXIF信息的,为啥非要从头来过。

大致代码如下:

image = Image.open("some_image.png")
# Read orientation info and correct the width and height.
# 274 is Orientation. You can find the index in ExifTags.TAGS
orientation_code = image.getexif().get(274)
if 8 == orientation_code:
    image = image.rotate(90, expand=True)
elif 3 == orientation_code:
    image = image.rotate(180, expand=True)
elif 6 == orientation_code:
    image = image.rotate(-90, expand=True)

或者用这个函数也能完成这个事儿:

image = PIL.ImageOps.exif_transpose(image)

如果你只想得到长宽的话……

image = Image.open("some_image.png")
width, height = image.width, image.height
# Read orientation info and correct the width and height.
# 274 is Orientation. You can find the index in ExifTags.TAGS
if image.getexif().get(274) in [6, 8]:
    width, height = height, width

其中旋转代码如下

EXIF Orientation ValueRow #0 is:Column #0 is:
1TopLeft side
2*TopRight side
3BottomRight side
4*BottomLeft side
5*Left sideTop
6Right sideTop
7*Right sideBottom
8Left sideBottom
NOTE: Values with “*” are uncommon since they represent “flipped” orientations.

如果你喜欢使用Scikit-image

对不起哈,这个暂时无解……它封装得比较多,我不能直接深入底层改读取函数。


嗯,大致就这样啦。祝各位食用愉快~


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注