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类型的
本人小白,如果有错误之处,还望不吝指正。