Skip to content

Manipulate EXIF and IFD metadata.

Notifications You must be signed in to change notification settings

Moustikitos/tyf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tyf

pypi pypi pypi pypi Downloads

Support this project

Liberapay receiving Paypal me

Why this package ?

Tyf package provides pythonic way to work with embeded data in TIFF and JPEG images.

Documentation

The Tyf Project [WIP]

Read / write EXIF and IFD data

  • read / edit EXIF and XMP data from JPEG images
  • read / edit IFD and XMP data from TIFF images
  • read / edit / use GEOTIFF data from IFD
  • work directly with python types

Do more with JPEG and TIFF files

  • extract TIFF or JPEG thumbnails from JPEG files
  • dump EXIF data from JPEG into file
  • dump location thumbnail using any map provider API

Quick view

>>> import Tyf
>>> tif = Tyf.open("test/CEA.tif")
>>> tif.__class__
<class 'Tyf.TiffFile'>
>>> for key in tif.gkd[0]: print(key)
... 
<GKD tag GTModelTypeGeoKey:(1,) - Projection Coordinate System>
<GKD tag GTRasterTypeGeoKey:(1,) - Raster pixel is area>
<GKD tag GTCitationGeoKey:b'unnamed'>
<GKD tag GeographicTypeGeoKey:(4267,) - NAD27>
<GKD tag GeogCitationGeoKey:b'NAD27'>
<GKD tag GeogAngularUnitsGeoKey:(9102,) - degree>
<GKD tag ProjectedCSTypeGeoKey:(32767,) - User-defined>
<GKD tag ProjectionGeoKey:(32767,) - User-defined>
<GKD tag ProjCoordTransGeoKey:(28,) - User-defined>
<GKD tag ProjLinearUnitsGeoKey:(9001,) - metre>
<GKD tag ProjStdParallel1GeoKey:(33.75,)>
<GKD tag ProjNatOriginLongGeoKey:(-117.333333333333,)>
<GKD tag ProjFalseEastingGeoKey:(0.0,)>
<GKD tag ProjFalseNorthingGeoKey:(0.0,)>
>>> tr = tif[0].getModelTransformation()
>>> tr(tif[0]["ImageWidth"]/2, tif[0]["ImageLength"]/2) 
(-13067.47757973173, 4240428.8435290195, 0.0)
>>> jpg = Tyf.open("test/IMG_20150730_210115.jpg")
unknown tag 18246 type [7]: <IFD tag Undefined:4> ignored
unknown tag 18249 type [7]: <IFD tag Undefined:75> ignored
>>> jpg.__class__
<class 'Tyf.JpegFile'>
>>> jpg["XPComment"]
<IFD tag XPComment:'For testing purpose only !'>
>>> jpg.xmp
<Element '{adobe:ns:meta/}xmpmeta' at 0x000001D6A2404130>
>>> jpg.get_xmp("Rating", ns="ADOBE").text
'4'
>>> jpg.set_xmp("UserComment", "Simple comment") 
<Element '{http://ns.adobe.com/exif/1.0/}UserComment' at 0x000001D6A24062F0>
>>> jpg.get_xmp("UserComment").text 
'Simple comment'
>>> jpg.save_thumbnail("test/test_thumb") # extension automatically added

EXIF thumbnail

There are 3 attributes to access data within Tyf.JpegFile :

  • ifd0 containing picture IFD, EXIF and eventually GPS data
  • ifd1 containing thubnail data
  • xmp containing XMP data

ifd0 and ifd1 are shortcut to the first and second IFD in ifd attribute which is itself a Tyf.TiffFile.

>>> jpg.ifd[0] == jpg.ifd0
True
>>> jpg.ifd[1] == jpg.ifd1
True
>>> jpg.ifd.__class__
<class 'Tyf.TiffFile'>
>>> jpg.ifd0[256]
2560
>>> jpg.ifd0["ImageWidth"]
2560
>>> jpg.ifd0[256], jpg.ifd0.get("ImageWidth").comment
(2560, 'Number of columns in the image, ie, the number of pixels per row')
>>> jpg.ifd0["GPSLongitude"]
5.1872093

Tyf.ifd.Ifd class

>>> jpg.ifd0.__class__
<class 'Tyf.ifd.Ifd'>
>>> for tag in jpg.ifd0.tags(): print(tag)
...
<IFD tag ImageWidth:2560>
<IFD tag ImageLength:1920>
<IFD tag Make:'Google'>
<IFD tag Model:'Nexus S'>
<IFD tag Orientation:1 - Normal>
<IFD tag Software:'KVT49L'>
<IFD tag DateTime:datetime.datetime(2015, 7, 30, 21, 1, 16)>
<IFD tag Artist:'THOORENS Bruno'>
<IFD tag YCbCrPositioning:1 - Centered>
<IFD tag Copyright:'THOORENS Bruno'>
<IFD tag Exif IFD:2286>
<IFD tag GPS IFD:4754>
<IFD tag XPTitle:'Beautifull Rainbow'>
<IFD tag XPComment:'For testing purpose only !'>
<IFD tag XPAuthor:'THOORENS Bruno'>
<IFD tag XPKeywords:'Rainbow;Belgium'>
<IFD tag ExposureTime:0.008333333333333333>
<IFD tag FNumber:2.6>
<IFD tag ExposureProgram:3 - Aperture priority>
<IFD tag ISOSpeedRatings:50>
<IFD tag ExifVersion:b'0220'>
<IFD tag DateTimeOriginal:datetime.datetime(2015, 7, 30, 21, 1, 16)>
<IFD tag DateTimeDigitized:datetime.datetime(2015, 7, 30, 21, 1, 16)>
<IFD tag ShutterSpeedValue:7.0>
<IFD tag ApertureValue:3.0>
<IFD tag BrightnessValue:6.0>
<IFD tag ExposureBiasValue:0.0>
<IFD tag MaxApertureValue:3.0>
<IFD tag MeteringMode:2 - Center Weighted Average>
<IFD tag Flash:0 - Flash did not fire>
<IFD tag FocalLength:3.43>
<IFD tag ColorSpace:1 - RGB>
<IFD tag PixelXDimension:2560>
<IFD tag PixelYDimension:1920>
<IFD tag ExposureMode:0 - Auto exposure>
<IFD tag WhiteBalance:0 - Auto white balance>
<IFD tag SceneCaptureType:0 - Standard>
<IFD tag GPSVersionID:(2, 2, 0, 0)>
<IFD tag GPSLatitudeRef:'N'>
<IFD tag GPSLatitude:51.2095416>
<IFD tag GPSLongitudeRef:'E'>
<IFD tag GPSLongitude:5.1872093>
<IFD tag GPSAltitudeRef:0 - Above sea level>
<IFD tag GPSAltitude:0.0>
<IFD tag GPSTimeStamp:datetime.time(19, 1, 7)>
<IFD tag GPSImgDirectionRef:'M'>
<IFD tag GPSImgDirection:33.0>
<IFD tag GPSProcessingMethod:b'ASCII\x00\x00\x00NETWORK'>
<IFD tag GPSDateStamp:datetime.date(2015, 7, 30)>
>>> jpg.ifd0.get("Orientation").info
'Normal'
>>> jpg.ifd0.get_location()
(5.1872093, 51.2095416, -0.0)
>>> from Tyf import ifd
>>> ifd.dump_mapbox_location(jpg.ifd0, "test/test_location.png")

5.1872093, 51.2095416

>>> jpg.ifd0.set_location(4.362859, 48.958472, 0)
>>> ifd.dump_mapbox_location(jpg.ifd0, "test/test_location2.png")

4.362859, 48.958472

Contribute

Bug report & feedback

Use project issues.

Add / modify / fix code

Guidance words: keep it simple and solid!

  1. open a issue to propose your contribution
  2. once issue is granted
    • fork this repository
    • edit your contribution
    • start a pull request