python读取图像的exif信息

python 读取图像的exif信息

前几天用PYQT做了一个工具,打开图片发现和原图像有一个转动的变化,后来发现是exif头的信息没有读取,当用open(“name.jpg”, ‘rb’) 以二进制流的形式打开图像,我们如何得到图像的exif信息呢?

import exifread

pip install exifread
导入exifread库,
f = open(filename, 'rb') tags = exifread.process_file(f)
如果你选择的图片有exif信息的话,打印一下tags会是一个字典类型,例如:

{
	"Image ImageDescription": (0x010E) ASCII= @ 18, 
	"Image Make": (0x010F) ASCII=SONY @ 2266, 
	"Image Model": (0x0110) ASCII=ILCE-6000 @ 2272, 
	"Image Orientation": (0x0112) Short=Rotated 180 @ 54, 
	"Image Software": (0x0131) ASCII=ILCE-6000 v3.20 @ 2282,
	"Image DateTime": (0x0132) ASCII=2015:01:13 04:27:23 @ 2298,
	"Image YCbCrPositioning": (0x0213) Short=Co-sited @ 90,
	"Image ExifOffset": (0x8769) Long=2318 @ 102,
	"Image SensitivityType": (0x8830) Short=Recommended Exposure Index @ 114,
	"Image RecommendedExposureIndex": (0x8832) Long=400 @ 126,
	"Image XPTitle": (0x9C9B) Byte=[0, 0] @ 138,
	"Image XPSubject": (0x9C9F) Byte=[32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, ... ] @ 42146,
	"Image LensSpecification": (0xA432) Ratio=[16, 50, 7/2, 28/5] @ 42210,
	"Image LensModel": (0xA434) ASCII=E PZ 16-50mm F3.5-5.6 OSS @ 42242,
	"Image PrintIM": (0xC4A5) Undefined=[80, 114, 105, 110, 116, 73, 77, 0, 48, 51, 48, 48, 0, 0, 3, 0, 2, 0, 1, 0, ... ] @ 42268,
	"Image Padding": (0xEA1C) Undefined=[] @ 206,
	"EXIF ExposureTime": (0x829A) Ratio=1/160 @ 4840,
	"EXIF FNumber": (0x829D) Ratio=28/5 @ 4848,
	"EXIF ExposureProgram": (0x8822) Short=Program Normal @ 2352,
	"EXIF ISOSpeedRatings": (0x8827) Short=400 @ 2364,
	"EXIF ExifVersion": (0x9000) Undefined=0230 @ 2376,
	"EXIF DateTimeOriginal": (0x9003) ASCII=2015:01:13 04:27:23 @ 4856,
	"EXIF DateTimeDigitized": (0x9004) ASCII=2015:01:13 04:27:23 @ 4876,
	"EXIF ComponentsConfiguration": (0x9101) Undefined=YCbCr @ 2412,
	"EXIF CompressedBitsPerPixel": (0x9102) Ratio=1 @ 4896,
	"EXIF BrightnessValue": (0x9203) Ratio=6917/1280 @ 4904,
	"EXIF ExposureBiasValue": (0x9204) Ratio=0 @ 4912,
	"EXIF MaxApertureValue": (0x9205) Ratio=159/32 @ 4920,
	"EXIF MeteringMode": (0x9207) Short=Pattern @ 2472,
	"EXIF LightSource": (0x9208) Short=Unknown @ 2484,
	"EXIF Flash": (0x9209) Short=Flash did not fire, auto mode @ 2496,
	"EXIF FocalLength": (0x920A) Ratio=50 @ 4928,
	"EXIF MakerNote": (0x927C) Undefined=[83, 79, 78, 89, 32, 68, 83, 67, 32, 0, 0, 0, 94, 0, 3, 16, 4, 0, 16, 0, ... ] @ 4936,
	"EXIF UserComment": (0x9286) Undefined=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] @ 42052,
	"EXIF SubSecTimeOriginal": (0x9291) ASCII=00 @ 2544,
	"EXIF SubSecTimeDigitized": (0x9292) ASCII=00 @ 2556,
	"EXIF FlashPixVersion": (0xA000) Undefined=0100 @ 2568,
	"EXIF ColorSpace": (0xA001) Short=sRGB @ 2580,
	"EXIF ExifImageWidth": (0xA002) Long=6000 @ 2592,
	"EXIF ExifImageLength": (0xA003) Long=3376 @ 2604,
	"Interoperability InteroperabilityVersion": (0x0002) Undefined=[48, 49, 48, 48] @ 42126,
	"EXIF InteroperabilityOffset": (0xA005) Long=42116 @ 2616,
	"EXIF FileSource": (0xA300) Undefined=Digital Camera @ 2628,
	"EXIF SceneType": (0xA301) Undefined=Directly Photographed @ 2640,
	"EXIF CustomRendered": (0xA401) Short=Normal @ 2652,
	"EXIF ExposureMode": (0xA402) Short=Auto Exposure @ 2664,
	"EXIF WhiteBalance": (0xA403) Short=Auto @ 2676,
	"EXIF DigitalZoomRatio": (0xA404) Ratio=1 @ 42136,
	"EXIF FocalLengthIn35mmFilm": (0xA405) Short=75 @ 2700,
	"EXIF SceneCaptureType": (0xA406) Short=Standard @ 2712,
	"EXIF Contrast": (0xA408) Short=Normal @ 2724,
	"EXIF Saturation": (0xA409) Short=Normal @ 2736,
	"EXIF Sharpness": (0xA40A) Short=Normal @ 2748,
	"EXIF Padding": (0xEA1C) Undefined=[] @ 2780,
	"EXIF OffsetSchema": (0xEA1D) Signed Long=4124 @ 2772
}

其中不同的key对应不同的信息,旋转信息在trags[‘Image Orientation’]中,打印出来是Rotated 180,说明旋转了180度,这样只需要在最后显示图片时预先调整一下就ok
另外在旋转90度时会出现两种 Rotated 90 CW 和 Rotated 90 CCW,第一种是顺时针旋转,第二种时逆时针旋转,Rotated 90 CCW 即为 270度。

PIL函数实现

如果使用PIL.Image类型的图像,我们可以用_getexif()函数实现,

def apply_exif_orientation(image):
	try:
	    exif = image._getexif()
	except AttributeError:
	    exif = None
	if exif is None:
	    return image
	exif = {PIL.ExifTags.TAGS[k]: v for k, v in exif.items() if k in PIL.ExifTags.TAGS}
	orientation = exif.get('Orientation', None)
	if orientation == 1:
             # do nothing
             return image
        elif orientation == 2:
            # left-to-right mirror
            return PIL.ImageOps.mirror(image)
        elif orientation == 3:
            # rotate 180
            return image.transpose(PIL.Image.ROTATE_180)
        elif orientation == 4:
            # top-to-bottom mirror
            return PIL.ImageOps.flip(image)
        elif orientation == 5:
            # top-to-left mirror
            return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_270))
        elif orientation == 6:
            # rotate 270
            return image.transpose(PIL.Image.ROTATE_270
        elif orientation == 7:
            # top-to-right mirror
            return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_90))
        elif orientation == 8:
            # rotate 90
            return image.transpose(PIL.Image.ROTATE_90)    
        else:
            return image

image 是PIL.Image类型的

本人小白,如果有错误之处,还望不吝指正。

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值