图片元信息Exif(Exchangeable Image File)的获取和修改

发布时间 2023-07-19 14:56:16作者: stardsd
我们进行图片分类,做一些人工智能的项目或者利用Python来对图片进行分类,都可以利用到Exif信息。

什么是Exif?

Exif是一种图像文件格式,实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及GPS全球定位系统数据、缩略图等。你可以利用任何可以查看JPEG文件的看图软件浏览Exif格式的照片,但并不是所有的图形程序都能处理Exif信息。

EXIF元信息被组织成一个图像中的不同图像文件目录(IFD)。这些IFD的名称与ExifTool系列1组的名称相对应。写入EXIF信息时,除非指定了另一个组,否则将使用下面列出的默认 组。

创建新的IFD时,可以使用默认值自动添加强制标签(在Writable类型之后用冒号表示),如果仅保留默认值的强制标签,则在删除标签时会自动删除IFD。

 

基本信息
中文名英文名类型支持类型
可执行交换文件 Exchangeable Image File(Exif) 图像文件格式 JJPG,TIFF,PNG,JP2,PGF,MIFF,HDP,PSP和XCF图像以及许多基于TIFF的RAW图像,甚至某些AVI中找到和MOV视频

Exif标准

EXIF(Exchangeable Image File)是"可交换图像文件"的缩写,当中包含了专门为数码相机的照片而定制的元数据,可以记录数码照片的拍摄参数、缩略图及其他属性信息。Exif标准最初由日本电子工业发展协会(JEIDA - Japan Electronic Industry Development Association)制订,目前的最新版本是发布于2010年04月的 Exif 2.3 版,该版本曾在2012年12月以及2013年5月有所修正 ,并已经应用到各个厂商的新影像设备中。

Exif 文件实际是JPEG文件的一种,遵从JPEG标准,只是在文件头信息中增加了有关拍摄信息的内容和索引图。所以你可以使用任何支持JPEG格式的图像工具软件观看 Exif 文件,但图像一旦被修改,Exif 信息可能会永久丢失,故编辑 Exif 必须使用专门的软件。

简单来说,Exif 信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部,也就是说 Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,它就好像是傻瓜相机的日期打印功能一样,只不过 Exif信息所记录的资讯更为详尽和完备。Exif 所记录的元数据信息非常丰富,主要包含了以下几类信息:

  • 拍摄日期
  • 拍摄器材(机身、镜头、闪光灯等)
  • 拍摄参数(快门速度、光圈F值、ISO速度、焦距、测光模式等)
  • 图像处理参数(锐化、对比度、饱和度、白平衡等)
  • 图像描述及版权信息
  • GPS定位数据
  • 缩略图

厂商注释

厂商注释(MakerNote)是储存在 Exif 中的厂商专有的注释数据,采用二进制格式,由不同的厂商自行制订,因此没有统一的标准,往往只能由生产商读取。厂商注释往往记录了许多 Exif 标准中未被正式定义的标签,比如快门次数、白平衡微调、人脸侦测信息、连拍序列、对焦数据等等,大大扩展了 Exif 标准的局限性。

由于缺乏统一的行业标准,加之设备生产商往往不对外公布其厂商注释采用的格式,使得解码和识别厂商注释变得十分困难。一般的 Exif 查看软件并不能解码厂商注释数据,目前能够正确读取并识别的厂商注释项目的Exif 查看/编辑软件比较少,主要有:ExifTool、MagicEXIF(中文支持)、bkviewer、JPEGsnoop(仅限佳能和尼康)等。

常见标签

所有的JPEG文件以字符串"0xFFD8"开头,并以字符串"0xFFD9"结束。文件头中有一系列"0xFF??"格式的字符串,称为"JPEG标识"或"JPEG段",用来标记JPEG文件的信息段。"0xFFD8"表示图像信息开始,"0xFFD9"表示图像信息结束,这两个标识后面没有信息,而其它标识紧跟一些信息字符。

0xFFE0 -- 0xFFD9之间的标识符称为"应用标记",一般称为APPn,JPEG的编码和解码并不会使用这些段,Exif 正是利用这些信息串记录拍摄信息如快门速度、光圈值等,甚至可以包括全球定位信息。按照 Exif 标准对这些标识符的定义,数码相机可以把各种拍摄信息记入数码图像中,应用软件可以读取这些数据,再按照 Exif 标准,检索出它们的具体含义,一般而言包括以下一些信息

标签号Exif 定义名中文定义名备注
0x010E ImageDescription 图像描述  
0x013B Artist 作者  
0x010F Make 生产商  
0x0110 Model 型号 相机型号
0x0112 Orientation 方向  
0x011A XResolution 水平方向分辨率  
0x011B YResolution 垂直方向分辨率  
0x0128 ResolutionUnit 分辨率单位  
0x0131 Software 软件 固件Firmware版本或者编辑软件
0x0132 DateTime 日期和时间 照片最后修改时间
0x0213 YCbCrPositioning YCbCr定位  
0x8769 ExifOffset Exif子IFD偏移量  
0x829A ExposureTime 曝光时间 快门速度
0x829D FNumber 光圈系数 光圈的F值
0x8822 ExposureProgram 曝光程序 自动曝光、光圈优先、快门优先、M档等
0x8827 ISOSpeedRatings ISO感光度  
0x9000 ExifVersion Exif 版本  
0x9003 DateTimeOriginal 拍摄时间 照片拍摄时间
0x9004 DateTimeDigitized 数字化时间 照片被写入时间
0x9204 ExposureBiasValue 曝光补偿  
0x9205 MaxApertureValue 最大光圈  
0x9207 MeteringMode 测光模式 平均测光、中央重点测光、点测光
0x9208 Lightsource 光源 一般记录白平衡
0x9209 Flash 闪光灯 闪光灯状态
0x920A FocalLength 镜头焦距 镜头物理焦距
0x927C MakerNote 厂商注释  
0x9286 UserComment 用户注释  
0xA000 FlashPixVersion FlashPix版本  
  ColorSpace 色彩空间 AdobeRGB、sRGB等
  ExifImageWidth 图像宽度  
0xA003 ExifImageLength 图像高度  
0xA433 LensMake 镜头生产商  
0xA434 LensModel 镜头型号  

作用

提高摄影水平

通过查看优秀作品的 Exif参数,你能够知道作者使用的器材,并且了解到作者所处的环境以及拍摄时使用的相机设置。通过比对Exif数据与图像内容,你可以直观地了解到曝光组合的不同会对图像产生什么影响、以及不同焦距的镜头会产生什么样的视觉效果等,从而在以后的拍摄中进行改进,这也是数码照片相对于传统胶片的一个重要优势。

版权维护

可以设置一些版权信息。

人工智能分类

Python等编程语言,利用Exif信息对图片进行分类、编辑等。常用的库有PIL 、PIL.ExifTags

提供编辑依据

很多图像编辑器会自动读取Exif数据来对图像进行优化,最常见的便是从 Exif中读取出相机姿态信息,从而自动识别出竖拍甚至是颠倒拍摄的照片并对其进行旋转校正。也有一些软件可以根据 Exif中的机内处理信息对图像进行针对性优化,从而保证图像不会因为过度处理而失真。

方便管理

Exif 除了记录技术性参数之外,还允许用户加入自定义的信息。比如通过 GPS 信息可以知道照片具体的拍摄地点,Windows 允许用户加入图像关键词便于用户日后的搜索和归类,加入图像描述或者注释还可以记录照片拍摄时的有趣故事。

验证原图

由于照片经过图像处理软件的编辑后会丢失部分或全部的 Exif元数据,因此 Exif信息的完整与否还是判断照片是否为相机直出的原始图像的重要依据。比如 Adobe Photoshop 在编辑图像后会删除大部分非技术参数,并将一些项目修改为其特有的值,因此很容易能够得知图像的编辑历史 。

包含地理信息

一般的单反相机拍摄的照片是不包含GPS信息的,除非增加相应的GPS附件。但是,我们每个人都有的手机,那可就不一样了。本身手机的内部就包含了GPS,所以在拍照的时候,照片就会自动记录下拍摄地的位置信息。这个就比较可怕了,你的照片就会暴露你的行踪。

回答大家问的比较多的几个问题

朋友圈的照片会不会泄露自己的位置?

这个当然不用担心啦,肯定不会的。我们在上传照片的时候,微信会把Exif信息隐藏掉。所以不必担心会暴露你的行踪。这里必须要提醒一下,如果你在聊天框内发送图片,并且是发送原图的情况下,那是会包含所有的Exif信息的哦!

别人修改过Exif元信息,我能查出来么?

这个问题可能不够准确,可能题主想问,如果用PS等软件修改过图片,能查出来吗?这些是会注入到EXif信息里面的,在Tags里面的软件一栏会提示Adobe Photoshop软件信息,修改时间等。但是,不排除遇上Exif大神,他可以把参数调整的天衣无缝。不过一般的Exif软件针对Exif元信息里面的一些标签是没有办法修改的,所以一般情况下,只要你修改了,都是会留下痕迹。还是那句话,不排除大神可以把参数平衡好。

原文链接:https://zhuanlan.zhihu.com/p/366726838


 

获取EXIF:

from PIL import Image
from PIL.ExifTags import TAGS


def get_jpeg_info(file):
    # Open the image with PIL
    image = Image.open(file)
    # Get the exif data of the image
    exif_data = image._getexif()
    # Get the YCbCr subsampling value from the exif data
    ycbcr_subsampling = exif_data.get(0x0212, None)
    # Get the MIME type from the exif data
    mime_type = exif_data.get(0x0103, None)
    # Return a tuple of the file name, YCbCr subsampling and MIME type
    return (file, ycbcr_subsampling, mime_type)


def get_exif_info(file):
    # Open the image with PIL
    image = Image.open(file)
    # Get the exif data of the image
    exif_data = image._getexif()
    # Create a dictionary to store the exif information
    exif_info = {}
    # Loop through the exif data items
    for tag, value in exif_data.items():
        # Get the tag name from the TAGS dictionary
        tag_name = TAGS.get(tag, tag)
        # Update the exif_info dictionary with the tag name and value pair
        exif_info[tag_name] = value
    # Return the exif_info dictionary
    return exif_info

  


 

修改:

There are different libraries that can help you modify the EXIF data of a JPEG file in Python. Some of them are:

import piexif
from PIL import Image

# Load the image and get the EXIF data as a dictionary
img = Image.open("image.jpg")
exif_dict = piexif.load(img.info["exif"])

# Modify the EXIF data, for example, change the date time
exif_dict["0th"][piexif.ImageIFD.DateTime] = "2023:01:01 00:00:00"

# Dump the EXIF data back to bytes
exif_bytes = piexif.dump(exif_dict)

# Save the image with the modified EXIF data
img.save("modified.jpg", "jpeg", exif=exif_bytes)

  

from exif import Image

# Open the image file and load it as an Image object
with open("image.jpg", "rb") as image_file:
    image = Image(image_file)

# Modify the EXIF data, for example, change the GPS latitude
image.gps_latitude = (10.0, 20.0, 30.0)

# Save the image with the modified EXIF data
with open("modified.jpg", "wb") as new_image_file:
    new_image_file.write(image.get_file())

  

from PIL import Image
from PIL.ExifTags import TAGS

# Load the image and get the EXIF data as a dictionary
image = Image.open("image.jpg")
exif_data = image._getexif()

# Modify the EXIF data, for example, change the orientation
exif_data[TAGS["Orientation"]] = 3

# Save the image with the modified EXIF data
image.save("modified.jpg", "jpeg", exif=image.info["exif"])