元数据(Metadata),又称中介数据、中继数据,为描述数据的数据(data about data),主要是描叙数据属性(property)的信息。用来支持如指示存储位置、历史数据、文件记录等功能。元数据就是关于数据的组织、数据域及其关系的信息,简而言之元数据就是关于数据的数据。
图片元信息(Metadata) 是嵌入到图片文件中的一些标签,可以类比为图片的属性,但是种类繁多。但是对于数码图像目前最常见的元数据类型有:EXIF、IPTC、XMP 这三种格式。
元数据的嵌入方式因图像的格式不同而不同,不同格式图像文件(eg: JPG, TIF, JPEG等)有不同的嵌入方式。
EXIF(exchangeable image file format, 简称Exif),是一种可交换图像文件的缩写,是专门为数码相机照片设定的可以记录数码照片的属性信息和拍摄数据。Exif 可以附加于 JPEG、TIFF等文件中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。
EXIF 最初是由图本电子工业发展协会在 1996 年制定版本为1.0。1988年升级到2.1,增加了对音频文件的支持。2002年3月发布 2.2 版。
Window7 操作系统具备对 Exif 的原生支持,通过鼠标右键点击图片 => 属性=> 详细信息标签即可查看 Exif 信息,注意 Exif 信息是可以被任意编辑因此 Exif 信息只能作为参考。
Exif 记录的元信息非常丰富,主要包含一下几类信息:
Pyexiv2 能够读写照片中携带的元信息包括 exif、iptc、xmp
Pyexiv2 安装
pip install pyexiv2
注意⚠️:该库支持小于 2G 图片读取,修改照片元信息支持小于 1G
class Image:
def __init__(self, filename, encoding='utf-8')
def read_exif(self, encoding='utf-8') -> dict
类 Image 基于图片途径打开一张图片,如下所示:
import pyexiv2
# 方式一:
img = pyexiv2.Image(r'./test/1.jpg')
data = img.read_exif()
# 注意当你获取图片信息后记得调用 close(),去关闭这个实例否则可能导致内存泄漏
img.close()
# 方式二:使用 with 打开图片会 image 实例会自动关闭
with pyexiv2.Image(r'./test/1.jpg') as img:
data = img.read_exif()
read_exif (获取图片 exif 信息)
img.read_exif()
read_iptc(获取图片 iptc 信息)
img.read_iptc
read_xmp(获取图片 xmp 信息以字典格式返回)
img.read_xmp
read_row_xmp(获取图片 xmp 信息以字符串形式返回)
img.read_row_xmp
from pyexiv2 import Image
def read_img_info(path):
img = Image(path)
exif_info = img.read_exif()
iptc_info = img.read_iptc()
xmp_info = img.read_xmp()
raw_xmp_info = img.read_raw_xmp()
print(raw_xmp_info)
img.close()
def modify_img_info(path):
img = Image(path)
origin_info = img(path).read_exif().get('Exif.Image.ImageDescription')
print(origin_info)
update_info = {'Exif.Image.ImageDescription': 'DCIM\\100MEDIA\\01.JPG'}
img.modify_exif(update_info)
result_data = img(path).read_exif().get('Exif.Image.ImageDescription')
print(result_data)
path = '/user/image/DJI_0835.jpg'
modify_img_info(path)
def clear_info(path):
img = Image(path)
img.clear_exif()
data = img.read_exif()
print(data)
Class ImageData 继承 class Image,该类通常被用做 bytes 类型获取照片信息
from pyexiv2 import Image
with open('/user/image/DJI_0835.jpg'm 'rb') as f:
with Image(f.read()) as img:
img.read_exif()
pip install exif
from exif import Image
with open('/user/image/DJI_0835.jpg', 'rb') as f:
img = Image(f)
has_exif 判断改照片是否携带 exif 信息
img.has_exif()
可以通过 dir(img)
查看 img 中携带的所有 tags
dir(img)
‘<unknown EXIF tag 59932>’, ‘<unknown EXIF tag 59933>’, ‘exif_ifd_pointer’, ‘gps_ifd_pointer’, ‘segments’, ‘aperture
value’, ‘brightness_value’, ‘color_space’, ‘components_configuration’, ‘compression’, ‘datetime’, ‘datetime_digitized’,
‘datetime_original’, ‘exif_version’, ‘exposure_bias_value’, ‘exposure_mode’, ‘exposure_program’, ‘exposure_time’, 'f
number’, ‘flash’, ‘flashpix_version’, ‘focal_length’, ‘focal_length_in_35mm_film’, ‘get’, ‘get_file’, ‘get_thumbnail’,
‘gps_altitude’, ‘gps_altitude_ref’, ‘gps_datestamp’, ‘gps_dest_bearing’, ‘gps_dest_bearing_ref’, 'gps_horizontal
positioning_error’, ‘gps_img_direction’, ‘gps_img_direction_ref’, ‘gps_latitude’, ‘gps_latitude_ref’, ‘gps_longitude’,
‘gps_longitude_ref’, ‘gps_speed’, ‘gps_speed_ref’, ‘gps_timestamp’, ‘has_exif’, ‘jpeg_interchange_format’, 'jpeg
interchange_format_length’, ‘lens_make’, ‘lens_model’, ‘lens_specification’, ‘make’, ‘maker_note’, ‘metering_mode’,
‘model’, ‘orientation’, ‘photographic_sensitivity’, ‘pixel_x_dimension’, ‘pixel_y_dimension’, ‘resolution_unit’,
‘scene_capture_type’, ‘scene_type’, ‘sensing_method’, ‘shutter_speed_value’, ‘software’, ‘subject_area’, 'subsec_time
digitized’, ‘subsec_time_original’, ‘white_balance’, ‘x_resolution’, ‘y_and_c_positioning’, ‘y_resolution’]
获取照片中 exif 信息
from exif import Image
with open('/user/image/DJI_0835.jpg', 'rb') as f:
img = Image(f)
latitude = img.gps_latitude
longitude = image.longitude
修改 exif 中某部分信息
img.gps_latitude = (36.0, 3.0, 11.08)
删除照片中某个信息
del.img.gps_latitude
del.img.gps_longitude