Manipulate EXIF and IFD metadata.

Overview

Tyf

Copyright

pypi

Distribution

pypi pypi pypi Downloads

Support this project

Liberapay receiving

Buy Ѧ and:

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 data from JPEG images
  • read / edit IFD data from TIFF images
  • read / edit GEOTIFF data from IFD
  • read / edit XMP data from IFD
  • work directly with python numbers, string and datetime
  • interpolate map coordinates using GEOTIFF ModelTransformation

Do more with JPEG and TIFF files

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

Quick view

>> jpg.__class__ >>> print(Tyf.xmp.tostring(jpg.xmp).decode()) Beautifull Rainbow Beautifull Rainbow THOORENS Bruno THOORENS Bruno 4 75 Rainbow Belgium Rainbow Belgium >>> jpg.save_thumbnail("test/test_thumb") # extension automatically added">
>>> import Tyf
>>> jpg = Tyf.open("test/IMG_20150730_210115.jpg")
>>> jpg.__class__
<class 'Tyf.JpegFile'>
>>> print(Tyf.xmp.tostring(jpg.xmp).decode()) 
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns3="http://ns.adobe.com/xap/1.0/" xmlns:ns4="http://ns.microsoft.com/photo/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:RDF><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b"><dc:title><rdf:Alt><rdf:li xml:lang="x-default">Beautifull Rainbow</rdf:li></rdf:Alt>
  </dc:title><dc:description><rdf:Alt><rdf:li xml:lang="x-default">Beautifull Rainbow</rdf:li></rdf:Alt>
  </dc:description><dc:creator><rdf:Seq><rdf:li>THOORENS Bruno</rdf:li></rdf:Seq>
  </dc:creator><dc:rights><rdf:Alt><rdf:li xml:lang="x-default">THOORENS Bruno</rdf:li></rdf:Alt>
  </dc:rights></rdf:Description><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" /><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b"><ns3:Rating>4</ns3:Rating></rdf:Description><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b"><ns4:Rating>75</ns4:Rating><ns4:LastKeywordXMP><rdf:Bag><rdf:li>Rainbow</rdf:li><rdf:li>Belgium</rdf:li></rdf:Bag>
  </ns4:LastKeywordXMP></rdf:Description><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b"><dc:subject><rdf:Bag><rdf:li>Rainbow</rdf:li><rdf:li>Belgium</rdf:li></rdf:Bag>
  </dc:subject></rdf:Description></rdf:RDF></ns0:xmpmeta>
>>> 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.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">
>>> 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.get_location() (5.1872093, 51.2095416, -0.0) >>> from Tyf import ifd >>> ifd.dump_mapbox_location(jpg.ifd0, "test/test_location.png")">
>>> 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
Comments
  • Unable to open tif file on Linux but works on Windows

    Unable to open tif file on Linux but works on Windows

    Salut,

    Ce problème n'apparait que sur une machine linux, le même fichier se lit correctement sur windows.

    Ci-dessous le message d'erreur:

    File "/usr/local/lib/python3.4/dist-packages/Tyf/__init__.py", line 58, in _read_IFD typ = TYPES[typ][0] KeyError: 0

    Dispo si besoin d'infos complémentaires

    Merci

    bug 
    opened by domlysz 12
  • Restricted Geokey ?

    Restricted Geokey ?

    Salut,

    J'ai une erreur avec un geotiff :

    /Tyf/gkd.py", line 105, in __init__
    ValueError: "GeogGeodeticDatumGeoKey" value must be one of [6016, ... 6001], get 6171 instead
    

    D'après la doc les valeurs entre 6000 et 6199 sont valides, le dictionnaire qu'ils présentent n'est donc pas exhaustif.

    Possible de lever cette restriction ?

    opened by domlysz 7
  • Issue with saving

    Issue with saving

    Hi there,

    I am guessing this is a recurrence of previous issues. This is a simple code: import numpy as np import Tyf import tifffile as tiff

    filename="Test.tif" outputname="output.tif"

    img = tiff.imread(filename) exif_info = Tyf.open(filename)

    tiff.imsave(outputname, img) exif_info.save(outputname)

    And I got following error: Traceback (most recent call last): File "J:/notebook/simple_test_exif.py", line 12, in exif_info.save(outputname) File "C:\Users\sean_\AppData\Local\Programs\Python\Python37\lib\site-packages\Tyf_init_.py", line 352, in save next_ifd = to_buffer(i, fileobj, next_ifd, byteorder) File "C:\Users\sean_\AppData\Local\Programs\Python\Python37\lib\site-packages\Tyf_init_.py", line 252, in to_buffer next_ifd_offset = dump(obj, fileobj, offset, byteorder) File "C:\Users\sean_\AppData\Local\Programs\Python\Python37\lib\site-packages\Tyf_init_.py", line 250, in dump dump(getattr(i, "%s"%tag), f, i.get(tag).value[0], b) File "C:\Users\sean\AppData\Local\Programs\Python\Python37\lib\site-packages\Tyf_init_.py", line 251, in dump return write_IFD(i,f,o,b) File "C:\Users\sean\AppData\Local\Programs\Python\Python37\lib\site-packages\Tyf_init_.py", line 162, in write_IFD pack(byteorder+fmt, fileobj, value) File "C:\Users\sean\AppData\Local\Programs\Python\Python37\lib\site-packages\Tyf_init_.py", line 14, in pack = lambda fmt, fileobj, value: fileobj.write(struct.pack(fmt, *value)) struct.error: ubyte format requires 0 <= number <= 255

    I've also attached the zipped TIF file for your reference. Could you please take a look?

    Thanks, Sean

    test.zip

    opened by seanliu-oss 5
  • wrong data type?

    wrong data type?

    I'm testing a script to read and write a 16bit RGB-colored tiff file and find some error on data type. My test script is very simple like:

    tif = Tyf.open(file_name)
    tif.save(new_file_name)
    

    and result in an error:

    struct.error: ubyte format requires 0 <= number <= 255
    

    After digging into the source file I find that data type of some tags might be wrong. For example in tags.py line 200, the ISOSpeedRatings tag type is set as 1, while it is of type 3 when read from a tiff file (use function _read_IFD in __init__.py). Several data type mismatches has been found, including ExposureProgram, MeteringMode, Flash, ColorSpace, FocalPlaneResolutionUnit, CustomRendered, ExposureMode, WhiteBalance, SceneCaptureType.

    I'm not sure whether it is a problem of a special file format or of the OS platform, or anything else. Does anyone has met similar problems?

    opened by LoveDaisy 4
  • Corrupted files (re)saving TIFF images

    Corrupted files (re)saving TIFF images

    Simple operation of (re)saving TIFF image file

    i1 = Tyf.open( '/Users/xatx/Desktop/TEST.tiff' ) i1.save( '/Users/xatx/Desktop/TESTTyf.tiff' )

    produces a corrupted file.

    opened by aritgithub 3
  • Push current repo and version to pip

    Push current repo and version to pip

    Ran into current pip: https://pypi.org/project/Tyf/ @ 1.3.2

    Ran into bugger:

    WARNING:  Traceback (most recent call last):
      File "<string>", line 29, in __plpython_procedure_find_exif_19256322
      File "/usr/local/lib/python3.5/dist-packages/Tyf/ifd.py", line 75, in decode
        return self._decoder(self.value)
      File "/usr/local/lib/python3.5/dist-packages/Tyf/decoders.py", line 54, in <lambda>
        _0x132 = _0x9003 = _0x9004 = lambda value: datetime.datetime.strptime(_2(value).decode(), "%Y:%m:%d %H:%M:%S")
    AttributeError: 'str' object has no attribute 'decode'
    

    Reviewed current code and this was supposed to be fixed. Current pip is old code? Not sure.

    opened by disarticulate 2
  • Error with InteropIFD : missing / corrupted after save

    Error with InteropIFD : missing / corrupted after save

    I have an issue with the sub IFD InteropIFD : when I load a jpg and save it, it is missing or shown as corrupt in exiftool after (with this example, it's corrupted). I guess it's not the expected behaviour.

    Before :

    Interoperability Index          : R98 - DCF basic file (sRGB)
    Interoperability Version        : 0100
    

    after :

    Warning                         : Bad InteropIFD directory
    

    Steps :

    jpg = Tyf.open('testori.jpg')
    #Print some tags
    for i in jpg.exif.tags():
        print(i)
    # eventually, (re)write 3-4 tags
    jpg.save('testinterop.jpg')
    

    The source file might be corrupted, but it should be original from the smartphone.

    Files : testori testinterop

    Python 3.5.2 64bit Win

    opened by u1735067 2
  • Use enum for the types ?

    Use enum for the types ?

    I may have missed the explanation about this, but I wanted to understand the format used in tags.py and I had to find what is the second field, then try to see where those values are used. I figured out it's Type after following code. Maybe a comment could be added to explain the format ? Also I think the type specification system used, ie. list of integers, is hard to follow and should be written as enum if possible ?

    Just my feedback from trying to understand how it works, but it might makes other/future maintainers life easier.

    opened by u1735067 2
  • location_dump doesnt not work sometimes

    location_dump doesnt not work sometimes

    Hello,

    at first thanks for this library!!!

    But i have little problem with some images. I wrote a script to add EXIF-Tags with GPS to Images which don't have any. This works ok as far i can see

    part of script:

            img = Image.open(os.path.join('pictures', filename))
            exf = img._getexif()
            exf[0]['GPSLatitude'] = lpi[2]
            exf[0]['GPSLongitude'] = lpi[1]
            exf[0]['GPSAltitude'] = 0.00
            exf[1]['GPSLatitude'] = lpi[2]
            exf[1]['GPSLongitude'] = lpi[1]
            exf[1]['GPSAltitude'] = 0.00
            img.save(os.path.join('tagged', 'tagged_' + filename), ifd=exf)
    

    but jpg.exif.dump_location doesnt create images of location. For any photo taken with my Iphone which adds GPS-Tags automatically it works.

    What did i miss??

    Thanks Peter

    opened by spacemishka 2
  • open(jpg) I/O operation on closed file

    open(jpg) I/O operation on closed file

    Hi, Windows 10, python 3.5, blender 2.77, Pillow throw an "I/O operation on closed file" exception on exif = Tyf.open(filepath) when filepath is a jpg.

    Seem to be a magic number issue

    opened by s-leger 1
  • a little help for a newbie

    a little help for a newbie

    Hi, I just stumbled across your Tyf library. I need to write exif data to tiff files. But I can't figure out how to do it. Could you kindly give me a short example on how to write a UserComment to a tif file, so that the rest of the exif info is preserved? Thanks...

    opened by ZacDiggum 1
Releases(1.4.3)
  • 1.4.3(Dec 27, 2020)

    $> python -m pip install Tyf==1.4.3
    

    New features

    • [x] issue #15 fix
    • [x] Tyf.ifd.Ifd class is now an iterable
    • [x] custom map provider url for location dumps
    • [x] minor bugfixes

    Work in progress

    • [ ] Code documentation

    TODO

    • [ ] Test suite
    Source code(tar.gz)
    Source code(zip)
Random collage/montage generator with drop-shadow

Random Collage Example Usage These are the sample input files in $PWD for the below examples: 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10

M B 1 Dec 07, 2021
Unique image & metadata generation using weighted layer collections.

nft-generator-py nft-generator-py is a python based NFT generator which programatically generates unique images using weighted layer files. The progra

Jonathan Becker 243 Dec 31, 2022
QR-Generator - An awesome QR Generator to create or customize your QR's

QR Generator An awesome QR Generator to create or customize your QR's! Table of

Tristán 1 Jan 28, 2022
将位图转为彩色矢量 svg 图片

一个将位图描摹为彩色矢量 svg 图片的程序,是一个命令行工具,使用 Python 脚本实现,运行环境 Python3.8+。 ✨ 效果 以一个字帖图片为例,这是 png 格式的位图(370KB): 这是颜

Haujet Zhao 104 Dec 30, 2022
Panel Competition Image Generator

Panel Competition Image Generator This project was build by a member of the NFH community and is open for everyone who wants to try it. Relevant links

Juliano Mendieta 1 Oct 22, 2021
Javascript image annotation tool based on image segmentation.

JS Segment Annotator Javascript image annotation tool based on image segmentation. Label image regions with mouse. Written in vanilla Javascript, with

Kota Yamaguchi 513 Nov 15, 2022
This piece of code is a User Welcomer with Image Manipulation using Python and Pillow (PIL).

This piece of code is a User Welcomer with Image Manipulation using Python and Pillow (PIL).

Bero 4 Jan 11, 2022
Python scripts for semi-automated morphometric analysis of atolls from Landsat satellite Imagery.

AtollGeoMorph Python scripts for semi-automated morphometric analysis of atolls from Landsat satellite Imagery. The python scripts included allow user

1 Dec 16, 2022
A simple image to text converter with GUI!

TEXTEMAGE! Textemage is a quick tool that extracts text from images, it is a Python based GUI program(also available in executable version). This is a

Akascape 5 Oct 26, 2022
This Github Action automatically creates a GIF from a given web page to display on your project README

This Github Action automatically creates a GIF from a given web page to display on your project README

Pablo Lecolinet 28 Dec 15, 2022
Paper backup of files using QR codes

Generate paper backups for Linux. Currently command-linux Linux only. Takes any file, and outputs a "paper backup": a printable black-and-white pdf fu

Zachary Vance 27 Dec 28, 2022
Design custom QR codes with this web app!

My-QR.Art This web app lets users design their own QR codes to any domain. It can be acessed on my-qr.art. You can find some more background info abou

Marien Raat 406 Dec 20, 2022
This is a python project which detects color of an image when you double click on it.

This is a python project which detects color of an image when you double click on it. You have to press ESC button to close the pop-up Image window. There are mainly two library CV2 and Pandas that a

Yashwant Kumar Singh 0 Aug 16, 2022
Extracts random colours from an image

EXTRACT COLOURS This repo contains all the project files. Project Description A Program that extracts 10 random colours from an image and saves the rg

David .K. Danso 3 Dec 13, 2021
A simple plugin to view APR images in napari

napari-apr-viewer A simple plugin to view APR images in napari This napari plugin was generated with Cookiecutter using @napari's cookiecutter-napari-

5 Jan 24, 2022
Photini - A free, easy to use, digital photograph metadata (Exif, IPTC, XMP) editing application for Linux, Windows and MacOS.

A free, easy to use, digital photograph metadata (Exif, IPTC, XMP) editing application for Linux, Windows and MacOS. "Metadata" is said to mea

Jim Easterbrook 120 Dec 20, 2022
Fill holes in binary 2D & 3D images fast.

Fill holes in binary 2D & 3D images fast.

11 Dec 09, 2022
Labelme is a graphical image annotation tool, It is written in Python and uses Qt for its graphical interface

Image Polygonal Annotation with Python (polygon, rectangle, circle, line, point and image-level flag annotation).

Kentaro Wada 9.6k Jan 09, 2023
👾 Python project to help you convert any image into a pixel art.

👾 Pixel Art Generator Python project to help you convert any image into a pixel art. ⚙️ Developer's Guide Things you need to get started with this co

Atul Anand 6 Dec 14, 2022
Blue noise image stippling in Processing (requires GPU)

Blue noise image stippling in Processing (requires GPU)

Mike Wong 141 Oct 09, 2022