携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
前言
在实际应用中,我们最常见的非文本数据非图像数据莫属。图像文件包含一组特定的元数据,可以读取这些元数据来过滤文件或执行其他操作。图像数据具有多种不同格式类型和不同的元数据定义。在本节中,我们将学习如何从 JPEG
和 PNG
中获取信息,以及如何将相同的信息编码为不同文件类型。
Pillow 库与图片文件类型
Pillow
可以说是在 Python
中处理图像的最佳通用第三方库。该库可以轻松读取最常见格式的图像文件,并进行进一步处理。我们还将使用 xmltodict
模块将一些数据从 XML
转换为字典数据类型。Pillow
和 xmltodict
库的安装和其它第三方库完全相同:
$ pip install pillow
$ pip install xmltodict
复制代码
JPG
文件可以直接存储 EXIF
信息,而 PNG
文件则存储 XMP
信息,这是一种更通用的标准,可以在其中包含 EXIF
数据。在大多数情况下,XMP
定义了一个相对可读的原始 XML
树结构。但在复杂情况下,XMP
使用 RDF
编码,RDF
是描述如何编码 XML
树的标准。
Python 读取图片文件
首先,导入需要使用的模块和函数:
>>> from PIL import Image
>>> from PIL.ExifTags import TAGS, GPSTAGS
>>> import xmltodict
复制代码
打开一张 JPG
格式的图片:
>>> img_1 = Image.open('photo-1.jpg')
复制代码
获取文件的宽度、高度和格式:
>>> img_1.height
3024
>>> img_1.width
4032
>>> img_1.format
'JPEG'
复制代码
检索图像的 EXIF
信息并将其转换为字典数据类型,并打印相机、使用的镜头以及拍摄时间:
>>> exif_info_1 = {TAGS.get(tag, tag): value for tag, value in img_1._getexif().items()}
>>> exif_info_1['Model']
'iPhone X'
>>> exif_info_1['LensModel']
'iPhone X back dual camera 4mm f/1.8'
>>> exif_info_1['DateTimeOriginal']
'2022:07:21 12:07:55'
复制代码
打开 PNG
格式图像并获取 XMP
信息:
>>> img_2 = Image.open('photo-2.png')
>>> img_2.height
1512
>>> img_2.width
2016
>>> img_2.format
'PNG'
>>> xmp_info = xmltodict.parse(img_2.info['XML:com.adobe.xmp'])
复制代码
获取 RDF
描述字段,其中包含我们要查找的所有值。检索相机型号( TIFF
值)、镜头型号( EXIF
值)和创建日期( XMP
值):
>>> rdf_info_2 = xmp_info['x:xmpmeta']['rdf:RDF']['rdf:Description']
>>> rdf_info_2['tiff:Model']
'iPhone X'
>>> rdf_info_2['exifEX:LensModel']
'iPhone X back dual camera 4mm f/1.8'
>>> rdf_info_2['xmp:CreateDate']
'2022-07-21T12:07:55.695'
复制代码
获取两张图片中的 GPS
信息,并将其转换成相同的格式,检查是否相同:
>>> gps_info_1 = {GPSTAGS.get(tag, tag): value for tag, value in
>>> exif_to_decimal(gps_info_1)
('N53.34690555555556', 'W6.247797222222222')
>>> rdf_to_decimal(rdf_info_2)
('N53.346905', 'W6.247796666666667')
复制代码
打开另一张不同的图片,获取创建日期和 GPS
信息,并检查它是否与其它照片匹配:
>>> img_3 = Image.open('photo-b.png')
>>> xmp_info = xmltodict.parse(img_3.info['XML:com.adobe.xmp'])
>>> rdf_info_3 = xmp_info['x:xmpmeta']['rdf:RDF']['rdf:Description']
>>> rdf_info_3['xmp:CreateDate']
'2022-07-08T18:16:57'
>>> rdf_to_decimal(rdf_info_3)
('N53.34984166666667', 'W6.260388333333333')
复制代码