pythonic读取和编辑ifd和exif标记的方法。
Tyf的Python项目详细描述
^ tt1}$包提供了查看和编辑ExIF数据的简单方法 TIFF和JPEG文件。
更改
1.3.2
- JpegFileapi更改
- JpegFile将xmp元数据保留为xml.etree.ElementTree.Element对象
- Ifd类管理转换标记
- 将find和place方法添加到Ifd类
- 编码器/解码器改进
1.3.1
- 编码器/解码器错误修复
- 已将__iter__添加到Ifd类
>>> jpg = Tyf.open("test.jpg") >>> for v in jpg.ifd0: print(v) ... ('ImageWidth', 2560) ('ImageLength', 1920) [...] ('GPSProcessingMethod', b'NETWORK') ('GPSDateStamp', datetime.datetime(2015, 12, 29, 0, 0))
1.3.0
- 错误修复问题10
- 子IFD API更改(添加子IFD递归性)
>>> jpg.ifd0 {256: <Tiff tag 0x100: ImageWidth = (2560,)>, 257: <Tiff tag 0x101: ImageLength = (1920,) >, 34853: <Tiff tag 0x8825: GPS IFD = (968,)>, 34665: <Tiff tag 0x8769: Exif IFD = (495,) >, 306: <Tiff tag 0x132: DateTime = b'2015:07:30 21:01:16\x00'>, 271: <Tiff tag 0x10f: Ma ke = b'Google\x00'>, 272: <Tiff tag 0x110: Model = b'Nexus S\x00'>, 305: <Tiff tag 0x131: Software = b'KVT49L\x00'>, 274: <Tiff tag 0x112: Orientation = (1,)> :: Normal, 531: <Ti ff tag 0x213: YCbCrPositioning = (1,)> :: Centered, 33432: <Tiff tag 0x8298: Copyright = b'Bruno THOORENS\x00'>, 40092: <Tiff tag 0x9c9c: XPComment = (83, 0, 105, 0, 109, 0, 112, 0, 108, 0, 101, 0, 32, 0, 99, 0, 111, 0, 109, 0, 109, 0, 101, 0, 110, 0, 116, 0, 97, 0, 105, 0, 114, 0, 101, 0, 32, 0, 101, 0, 110, 0, 32, 0, 97, 0, 115, 0, 99, 0, 105, 0, 105, 0, 32, 0, 112, 0, 111, 0, 117, 0, 114, 0, 32, 0, 88, 0, 80, 0)>} >>> jpg.ifd0.exif {36864: <Exif tag 0x9000: ExifVersion = b'0220'>, 37377: <Exif tag 0x9201: ShutterSpeedVa lue = (70, 10)>, 37378: <Exif tag 0x9202: ApertureValue = (30, 10)>, 36867: <Exif tag 0x9 003: DateTimeOriginal = b'2015:12:29 08:00:00\x00'>, 36868: <Exif tag 0x9004: DateTimeDig itized = b'2015:07:30 21:01:16\x00'>, 37381: <Exif tag 0x9205: MaxApertureValue = (30, 10 )>, 37510: <Exif tag 0x9286: UserComment = b'ASCII\x00\x00\x00Simple commentaire en ascii '>, 37383: <Exif tag 0x9207: MeteringMode = (2,)> :: Center Weighted Average, 37385: <Exi f tag 0x9209: Flash = (0,)> :: Flash did not fire, 37386: <Exif tag 0x920a: FocalLength = (343, 100)>, 41986: <Exif tag 0xa402: ExposureMode = (0,)> :: Auto exposure, 40963: <Exi f tag 0xa003: PixelYDimension = (1920,)>, 37380: <Exif tag 0x9204: ExposureBiasValue = (0 , 0)>, 33434: <Exif tag 0x829a: ExposureTime = (1, 120)>, 33437: <Exif tag 0x829d: FNumbe r = (26, 10)>, 34850: <Exif tag 0x8822: ExposureProgram = (3,)> :: Aperture priority, 409 61: <Exif tag 0xa001: ColorSpace = (1,)> :: RGB, 41990: <Exif tag 0xa406: SceneCaptureTyp e = (0,)> :: Standard, 34855: <Exif tag 0x8827: ISOSpeedRatings = (50,)>, 41987: <Exif ta g 0xa403: WhiteBalance = (0,)> :: Auto white balance, 37379: <Exif tag 0x9203: Brightness Value = (60, 10)>, 40962: <Exif tag 0xa002: PixelXDimension = (2560,)>} >>> jpg.ifd0.gps {0: <GPS tag 0x0: GPSVersionID = (2, 2, 0, 0)>, 1: <GPS tag 0x1: GPSLatitudeRef = b'N\x00 '> :: North latitude, 2: <GPS tag 0x2: GPSLatitude = (43, 1, 30, 1, 0, 1)>, 3: <GPS tag 0 x3: GPSLongitudeRef = b'E\x00'> :: East longitude, 4: <GPS tag 0x4: GPSLongitude = (3, 1, 30, 1, 0, 1)>, 5: <GPS tag 0x5: GPSAltitudeRef = (1,)> :: Below sea level, 6: <GPS tag 0 x6: GPSAltitude = (20, 1)>, 7: <GPS tag 0x7: GPSTimeStamp = (8, 1, 0, 1, 0, 1)>, 16: <GPS tag 0x10: GPSImgDirectionRef = b'M\x00'> :: Magnetic direction, 17: <GPS tag 0x11: GPSIm gDirection = (33, 1)>, 27: <GPS tag 0x1b: GPSProcessingMethod = b'ASCII\x00\x00\x00NETWOR K'>, 29: <GPS tag 0x1d: GPSDateStamp = b'2015:12:29\x00'>}
1.2.5
- 错误修复问题5
- 错误修复问题6
1.2.4
- 将set_location和get_location添加到Ifd类
>>> from Tyf.ifd import Ifd >>> ifd = Ifd() >>> ifd.set_location(-4.362746, 48.958474, -152.2356) >>> for tag in ifd.tags(): print(tag) ... <GPS tag 0x1: GPSLatitudeRef = b'N\x00'> :: 'North latitude' <GPS tag 0x2: GPSLatitude = (48, 1, 57, 1, 38133, 1250)> <GPS tag 0x3: GPSLongitudeRef = b'W\x00'> :: 'West longitude' <GPS tag 0x4: GPSLongitude = (4, 1, 21, 1, 57357, 1250)> <GPS tag 0x5: GPSAltitudeRef = (1,)> :: 'Below sea level' <GPS tag 0x6: GPSAltitude = (380589, 2500)> >>> ifd.get_location() (-4.362746, 48.958474, -152.2356)
1.2.3
- Tyf.Image.save方法的错误修复
- 为verion测试添加了__PY3__变量
1.2.2
- Tyf.gkd.Gkd.to_ifd方法的错误修复
1.2.1
- 问题1的错误修复
1.2.0
- PIL(pillow)集成JPEG图像
1.1.3
- 已将load_location&;dump_location添加到Ifd类
- 已将dump_exif&;load_exif添加到JpegFile类
1.1.2
- JpegFile类现在处理jpeg和tiff缩略图
- 为JpegFile类添加了save_thumbnail方法
- TiffFile仅在需要或按需加载光栅数据
- 为TiffFile类添加了load_raster方法
- _2编码器修复(ascii编码器)
- 代码调整
1.1.1
- 增加了阅读自定义子ifd的习惯性
- _5编码器修复(rational编码器)
- __repr__格式更新
- 已删除JpegFile类的thumbnail属性
1.1亿
- 添加了编码器/解码器
- 已将ifd1属性添加到JpegFile类
- 已将exif_ifd属性添加到Ifd类
- 已将gps_ifd属性添加到Ifd类
1.0b1
- Windows Explorer 修改的EXIF数据修正错误
- 添加了xp标记
1.0b0
- 为TiffFile类添加了gkd属性
- 为JpegFile类添加了exif属性 LI>读写IFD和EXIF数据< /LI>
- TiffFile使用+运算符(即多图像TIFF文件)连接
0.9A1
- 使用TiffFile类进行多个ifd管理
- 为JpegFile和TiffFile类添加了save方法
- 为JpegFile类添加了thumbnail属性
0.8A4
- 第一个一致性版本
快速查看
>>> import Tyf
Tag
>>> import Tyf >>> t = Tyf.ifd.Tag("GPSLongitude") >>> t.digest(4.362743) >>> t <Orphan tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)> >>> t = Tyf.ifd.Tag("GPSLongitude", value=4.362743) >>> t <Orphan tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)> >>> t.type 5 >>> t.count 3 >>> t.value (4, 1, 21, 1, 114687, 2500) >>> t.decode() 4.362743 >>> t = Tyf.ifd.Tag("KeyTest") <Orphan tag 0x0: Undefined = ''>
Ifd
>>> from Tyf import tags >>> ifd = Tyf.ifd.Ifd(tag_family=[tags.bTT, tags.xTT, tags.pTT]) >>> ifd["Copyright"] = "Bruno THOORENS" >>> ifd >>> ifd {33432: <Tiff tag 0x8298: Copyright = b'Bruno THOORENS\x00'>} >>> gps_ifd = ifd["GPS IFD"] # create "GPS IFD" sub ifd in ifd >>> gps_ifd.append(t) >>> gps_ifd # t is no more orphan {4: <GPS tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)>} >>> gps_ifd["GPSLongitudeRef"] = gps_ifd["GPSLongitude"] >>> gps_ifd["GPSLatitude"] = gps_ifd["GPSLatitudeRef"] = 48.958474 >>> gps_ifd {1: <GPS tag 0x1: GPSLatitudeRef = b'N\x00'> :: North latitude, 2: <GPS tag 0x2: GPSLatit ude = (48, 1, 57, 1, 38133, 1250)>, 3: <GPS tag 0x3: GPSLongitudeRef = b'E\x00'> :: East longitude, 4: <GPS tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)>} >>> ifd.dump_location("./pypi_test_location", format="jpg", size="512x256")
缩略图位置可以从谷歌^ {TT661 } API下载,如果存在所有纬度和经度标签。
>>> for tag in ifd.tags(): print(tag) ... <Tiff tag 0x8298: Copyright = b'Bruno THOORENS\x00'> <Tiff tag 0x8825: GPS IFD = (0,)> <GPS tag 0x1: GPSLatitudeRef = b'N\x00'> :: North latitude <GPS tag 0x2: GPSLatitude = (48, 1, 57, 1, 38133, 1250)> <GPS tag 0x3: GPSLongitudeRef = b'E\x00'> :: East longitude <GPS tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)>
to_buffer
>>> from io import BytesIO as StringIO >>> s = StringIO() >>> Tyf.to_buffer(ifd, s, offset=0) 195 >>> s.getvalue() b'\x02\x00\x98\x82\x02\x00\x0f\x00\x00\x00\x1e\x00\x00\x00%\x88\x04\x00\x01\x00\x00\x00-\ x00\x00\x00\x00\x00\x00\x00Bruno THOORENS\x00\x04\x00\x01\x00\x02\x00\x02\x00\x00\x00N\x0 0\x00\x00\x02\x00\x05\x00\x03\x00\x00\x00c\x00\x00\x00\x03\x00\x02\x00\x02\x00\x00\x00E\x 00\x00\x00\x04\x00\x05\x00\x03\x00\x00\x00{\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x01\ x00\x00\x009\x00\x00\x00\x01\x00\x00\x00\xf5\x94\x00\x00\xe2\x04\x00\x00\x04\x00\x00\x00\ x01\x00\x00\x00\x15\x00\x00\x00\x01\x00\x00\x00\xff\xbf\x01\x00\xc4\t\x00\x00'
from_buffer
>>> s.seek(0) 0 >>> ifd1 = Tyf.ifd.Ifd(tag_family=[tags.bTT, tags.xTT, tags.pTT]) >>> Tyf.from_buffer(ifd1, s, offset=0) 0 >>> ifd1 {33432: <Tiff tag 0x8298: Copyright = b'Bruno THOORENS\x00'>, 34853: <Tiff tag 0x8825: GP S IFD = (45,)>} >>> ifd1.gps_ifd {1: <GPS tag 0x1: GPSLatitudeRef = b'N\x00'> :: 'North latitude', 2: <GPS tag 0x2: GPSLat itude = (48, 1, 57, 1, 38133, 1250)>, 3: <GPS tag 0x3: GPSLongitudeRef = b'E\x00'> :: 'Ea st longitude', 4: <GPS tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)>} >>> for tag in ifd1.tags(): print(tag) ... <Tiff tag 0x8298: Copyright = b'Bruno THOORENS\x00'> <Tiff tag 0x8825: GPS IFD = (45,)> <GPS tag 0x1: GPSLatitudeRef = b'N\x00'> :: North latitude <GPS tag 0x2: GPSLatitude = (48, 1, 57, 1, 38133, 1250)> <GPS tag 0x3: GPSLongitudeRef = b'E\x00'> :: East longitude <GPS tag 0x4: GPSLongitude = (4, 1, 21, 1, 114687, 2500)> >>> ifd1["GPS IFD"]["GPSLongitude"] 4.362743
open
Tyf包导出open函数。它返回JpegFile或 TiffFile类,用于启用元数据读写。
>>> import Tyf >>> jpg = Tyf.open(r".\IMG_20150730_210115.jpg") >>> tif = Tyf.open(r".\CEA.tif") >>> isinstance(jpg, list) True >>> isinstance(tif, list) True
JpegFile
JpegFile类是映射在JPEG文件中找到的所有标记的列表。 值存储为二进制数据,除了0xffe1一个存储为TiffFile 实例或bytes对象(xmp数据)。
>>> type(jpg.ifd) <class 'Tyf.TiffFile'> >>> len(jpg.ifd) 2 >>> jpg.ifd0 # shortcut to jpg.ifd[0] {256: <Tiff tag 0x100: ImageWidth = (2560,)>, 305: <Tiff tag 0x131: Software = b'KVT49L\x 00'>, 274: <Tiff tag 0x112: Orientation = (1,)> :: Normal, 531: <Tiff tag 0x213: YCbCrPos itioning = (1,)> :: Centered, 34853: <Tiff tag 0x8825: GPS IFD = (572,)>, 257: <Tiff tag 0x101: ImageLength = (1920,)>, 34665: <Tiff tag 0x8769: Exif IFD = (176,)>, 306: <Tiff ta g 0x132: DateTime = b'2015:07:30 21:01:16\x00'>, 272: <Tiff tag 0x110: Model = b'Nexus S\ x00'>, 271: <Tiff tag 0x10f: Make = b'Google\x00'>} >>> jpg.ifd1 # shortcut to jpg.ifd[1] {256: <Tiff tag 0x100: ImageWidth = (320,)>, 257: <Tiff tag 0x101: ImageLength = (240,)>, 274: <Tiff tag 0x112: Orientation = (1,)> :: Normal, 259: <Tiff tag 0x103: Compression = (6,)> :: JPEG, 513: <Tiff tag 0x201: JPEGInterchangeFormat = (966,)>, 296: <Tiff tag 0x1 28: ResolutionUnit = (2,)> :: Inch, 282: <Tiff tag 0x11a: XResolution = (72, 1)>, 283: <T iff tag 0x11b: YResolution = (72, 1)>, 514: <Tiff tag 0x202: JPEGInterchangeFormatLength = (9624,)>} >>>jpg.xmp <Element '{adobe:ns:meta/}xmpmeta' at 0x3307a90>所有信息,包括GPS和EXIFF IFD都可用^ {TT75 }$ 其第一项的方法
>>> for tag in jpg.ifd0.tags(): print(tag) ... <Tiff tag 0x100: ImageWidth = (2560,)> <Tiff tag 0x101: ImageLength = (1920,)> [...] <GPS tag 0x1b: GPSProcessingMethod = b'ASCII\x00\x00\x00NETWORK'> <GPS tag 0x1d: GPSDateStamp = b'2015:07:30\x00'>
嵌入在JPEG文件中的JPEG或TIFF缩略图可以提取到单个文件中
>>> jpg.save_thumbnail(".\test_thumb") # file extension will be appended automaticaly
因为JpegFile.ifd0实际上是Tyf.ifd.Ifd实例的快捷方式:
>>> jpg.ifd0.dump_location("./pypi_test_location1", format="jpg")
TiffFile
TiffFile类是在TIFF文件中找到的ifd的列表。每个国际单项体育联合会都是一本字典 包含标记值对。
>>> for tag in tif[0].tags(): print(tag) ... <Tiff tag 0x100: ImageWidth = (514,)> <Tiff tag 0x101: ImageLength = (515,)> [...] <Tiff tag 0x87b0: GeoDoubleParamsTag = (-117.333333333333, 33.75, 0.0, 0.0)> <Tiff tag 0x87b1: GeoAsciiParamsTag = b'unnamed|NAD27|\x00'>
如果要求(或需要),任何RA将加载找到的ster数据。
>>> tif.has_raster True >>> tif.raster_loaded False >>> tif.load_raster() >>> tif.raster_loaded True
geotiff数据也可以从ifd中提取。
>>> geotiff = tif.gkd >>> for tag in geotiff[0].tags(): print(tag) # geotiff from the first ifd ... <Geotiff Tag 0x400: GTModelTypeGeoKey = (1,)> :: Projection Coordinate System <Geotiff Tag 0x401: GTRasterTypeGeoKey = (1,)> :: Raster pixel is area <Geotiff Tag 0x402: GTCitationGeoKey = b'unnamed'> <Geotiff Tag 0x800: GeographicTypeGeoKey = (4267,)> :: NAD27 [...] <Geotiff Tag 0xc0a: ProjFalseEastingGeoKey = (0.0,)> <Geotiff Tag 0xc0b: ProjFalseNorthingGeoKey = (0.0,)> >>> mt = geotiff[0].getModelTransformation() >>> mt(50, 50) # compute pixel coordinates (-25492.059935252837, 4252883.436953031, 0.0, 1.0)
PIL集成
>>> from Tyf import Image >>> img = Tyf.Image.open(r".\IMG_20150730_210115.jpg") >>> img <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=2560x1920 at 0x32B26B0> >>> exf = img._getexif() >>> exf [{256: <Tiff tag 0x100: ImageWidth = (2560,)>, 305: <Tiff tag 0x131: Software = b'KVT49L\ x00'>, 274: <Tiff tag 0x112: Orientation = (1,)> :: Normal, 531: <Tiff tag 0x213: YCbCrPo sitioning = (1,)> :: Centered, 34853: <Tiff tag 0x8825: GPS IFD = (572,)>, 257: <Tiff tag 0x101: ImageLength = (1920,)>, 34665: <Tiff tag 0x8769: Exif IFD = (176,)>, 306: <Tiff t ag 0x132: DateTime = b'2015:07:30 21:01:16\x00'>, 272: <Tiff tag 0x110: Model = b'Nexus S \x00'>, 271: <Tiff tag 0x10f: Make = b'Google\x00'>}, {256: <Tiff tag 0x100: ImageWidth = (320,)>, 257: <Tiff tag 0x101: ImageLength = (240,)>, 274: <Tiff tag 0x112: Orientation = (1,)> :: Normal, 259: <Tiff tag 0x103: Compression = (6,)> :: JPEG, 513: <Tiff tag 0x20 1: JPEGInterchangeFormat = (966,)>, 296: <Tiff tag 0x128: ResolutionUnit = (2,)> :: Inch, 282: <Tiff tag 0x11a: XResolution = (72, 1)>, 283: <Tiff tag 0x11b: YResolution = (72, 1 )>, 514: <Tiff tag 0x202: JPEGInterchangeFormatLength = (9624,)>}] >>> exf.__class__ <class 'Tyf.TiffFile'> >>> exf[0]["UserComment"] = "Simple commentaire" >>> exf[0]["Copyright"] = "Bruno THOORENS" >>> img.save(r".\test.jpg", ifd=exf) # write JPEG image with exif