前几天用PYQT做了一个工具,打开图片发现和原图像有一个转动的变化,后来发现是exif头的信息没有读取,当用open(“name.jpg”, ‘rb’) 以二进制流的形式打开图像,我们如何得到图像的exif信息呢?
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.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类型的
本人小白,如果有错误之处,还望不吝指正。