pythonic读取和编辑ifd和exif标记的方法。

Tyf的Python项目详细描述


^ tt1}$包提供了查看和编辑ExIF数据的简单方法 TIFFJPEG文件。

更改

1.3.2

  • JpegFileapi更改
  • JpegFile将xmp元数据保留为xml.etree.ElementTree.Element对象
  • Ifd类管理转换标记
  • findplace方法添加到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_locationget_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

  • PILpillow)集成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管理
  • JpegFileTiffFile类添加了save方法
  • 满^ {tT3}$ExIFF读(IFt0和IFD1为^ {tt56}$标记)
  • 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")
https://raw.githubusercontent.com/Moustikitos/tyf/master/test/pypi_test_location.jpg

缩略图位置可以从谷歌^ {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函数。它返回JpegFileTiffFile类,用于启用元数据读写。

>>> 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
https://raw.githubusercontent.com/Moustikitos/tyf/master/test/test_thumb.jpg

因为JpegFile.ifd0实际上是Tyf.ifd.Ifd实例的快捷方式:

>>> jpg.ifd0.dump_location("./pypi_test_location1", format="jpg")
https://raw.githubusercontent.com/Moustikitos/tyf/master/test/pypi_test_location1.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

支持此项目

http://bruno.thoorens.free.fr/img/gratipay.png

-

http://bruno.thoorens.free.fr/img/bitcoin.png

3jgib9sqidlyml7qkbytjukhq2nyg6z63d

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
在Java中使用Kotlin值类   在Hadoop中表示大文本块作为键的java   java安卓工作室;布局设计视图;   字典Java确定字符串是否以映射中的键开头   JavaG1:混合gc和完全gc之间有什么区别?   java Camunda升级组织。阿帕奇。平民语言错误   java Scanner类具有NextLine无限循环   安卓 GCM Java服务器:发送带有重音字符的消息   java我正在构建一个兴趣计算应用程序,我的项目构建良好,有1个警告,但它不会在我的设备上打开   java在Tilera TileGX上构建OpenJDK 8   GUI中的java惰性初始化与急切初始化   java JodaTime四舍五入到最近的一刻钟   java如何限制菜单。SpringRoo中的jspx可以避免对其他用户的实体执行CRUD操作   java我应该将缓冲流链接到输入流,还是在将声音库作为嵌入式资源加载时使用URL类?