图片中的exif数据

  前两天python群中一位女神发了一张照片,虽然只是个风景照。但是我突然想起之前在读 <> 时书中有讲到在图片中包含exif(exchange image file format),exif标准定义了如何存储图片和音频文件的标准,包含文档的作者,修改时间甚至有可能包含照片的GPS位置信息。(事实上不止图片,文档,表格,音频,视频都有类似exif的元数据)。

    from PIL import Image
    from PIL.ExifTags import TAGS
    img = Image.open(r"1.jpg")
    for tag,value in img._getexif().items():
        print(TAGS.get(tag,tag),value)
程序运行结果如下:
    ('ImageWidth', 5312)
    ('ImageLength', 2988)
    ('JpegIFByteCount', 0)
    ('WhiteBalance', 0)
    ('UserComment', u'\n')
    ('MeteringMode', 65535)
    ('LightSource', 0)
    ('Flash', 0)
    ('FocalLength', (480, 100))
    ('Orientation', 0)
    ('Make', u'samsung')
    ('Model', u'SM-N9100\x00')
    ('DateTime', u'2016:05:07 15:32:37')
    ('JpegIFOffset', 258)
    ('ExifOffset', 228)

但是经过我各种百度和谷歌之后,并没有找到PIL修改exif信息的操作,希望知道如何用PIL操作exif的各位看官在下面留个言。为此我不得不寻求与其他库,比如piexif(https://pypi.python.org/pypi/piexif)。
根据官方文档显示,piexif只有五个函数,使用起来确实很简单。本文就不充当文档解释的工作了,直接给一个完整的自己写的class。

import piexif
from piexif import ImageIFD # 0th
from piexif import ExifIFD # Exif
from piexif import GPSIFD # GPS
from piexif import InteropIFD #interop

class Exif(dict):
    Group_0th = "0th"
    Group_1st = "1st"
    Group_Exif = "Exif"
    Group_GPS = "GPS"
    Group_Interop = "Interop"
    Group_Thumbnail = "thumbnail"
    _unkown_tag = {"name":"unkown","type":"unkown"}
    def __init__(self,path):
        dict.__init__(self)
        self.__name = path
        self.update(piexif.load(self.__name))

    def pretty_dict(self):
        """print exif info"""
        ret_dict = {}
        for group,group_value in self.items():
            ret_dict.setdefault(group,{})
            if group_value is not None and group_value:
                for tag,value in group_value.items():
                    name = piexif.TAGS[group].get(tag,self._unkown_tag)["name"]
                    ret_dict[group][name] = value
        return ret_dict

    def as_byte(self):
        """for raw write exif to image"""
        return piexif.dump(self)

    def write(self,path=None):
        piexif.insert(self.as_byte(),path or self.__name)

    def insert_exif(self,group,tags):
        """group is one of Group_0th,Group_1st,Group_Exif,
                         Group_GPS,Group_Interop,Group_Thumbnail
            tags reference class ImageIFD,ExifIFD,GPSIFD,InteropIFD
        """
        if isinstance(tags,dict):
            for tag,value in tags.items():
                self[group][tag] = value
        elif isinstance(tags,list) or isinstance(tags,tuple):
            for tag,value in tags:
                self[group][tag] = value

    def remove_exif(self,group,tag=None):
        """group is one of Group_0th,Group_1st,Group_Exif,
                         Group_GPS,Group_Interop,Group_Thumbnail
            tags reference class ImageIFD,ExifIFD,GPSIFD,InteropIFD
        """
        if tag is None:
            self[group] = {}
        elif tag in self[group]:
            del self[group][tag]

下图是一个添加了exif信息的图片头:
这里写图片描述
FF D8 是jpg文件的标识头
FF E1 Exif头部开始标志
00 29 根据jpeg标准,29(注意,这是十六进制)是段内容和段长度本身但不包括段标识和段类型的长度
45 79 69 66 00 00 Exif内容的前缀(这是固定的)
4D 4D 00 2A …… 45 49 00 FF Exif内容
可以看出,exif信息只是填充在jpg文件中的一个FF E1打头的注释段,填充在文件头部。

你可能感兴趣的:(python)