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)
A Python3 library to generate dynamic SVGs

The Python library for generating dynamic SVGs using Python3

1 Dec 23, 2021
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
Pnuemonia Normal detection by using XRay images.

Pnuemonia Normal detection by using XRay images. Got image datas from kaggle(link is given in sources.txt file) also normal xray images from other site (also link is given) in order to avoid data dis

Zarina 1 Feb 28, 2022
Image Processing - Make noise images clean

影像處理-影像降躁化(去躁化) (Image Processing - Make Noise Images Clean) 得力於電腦效能的大幅提升以及GPU的平行運算架構,讓我們能夠更快速且有效地訓練AI,並將AI技術應用於不同領域。本篇將帶給大家的是 「將深度學習應用於影像處理中的影像降躁化 」,

2 Aug 04, 2022
Alternate Python bindings for the Open Asset Import Library (ASSIMP)

Impasse A simple Python wrapper for assimp using cffi to access the library. Requires Python = 3.7. It's a fork of PyAssimp, Assimp's official Python

Salad Dais 3 Sep 26, 2022
A tool and a library for SVG path data transformations.

SVG path data transformation toolkit A tool and a library for SVG path data transformations. Currently it supports a translation and a scaling. Usage

Igor Mikushkin 2 Mar 07, 2022
PyGram Instagram-like image filters.

PyGram Instagram-like image filters. Usage First, import the client: from filters import * Instanciate a filter and apply it: f = Nashville("image.jp

Ajay Kumar Nagaraj 102 Feb 21, 2022
Image enhancing model for making a blurred image to be somehow clearer than before

This is a very small prject which helps in enhancing the images by taking a Input images. This project has many features like detcting the faces and enhaning the faces itself and also a feature which

3 Dec 03, 2021
A linear stairs generation add-on for Blender

Linear Stairs Generator Table of Contents Installation Usage Screenshots Important Notes Requirements Blender 3.0 or newer. Installation: Download a z

Elhanan Flesch 4 May 17, 2022
Collection of SVG diagrams about how UTF-8 works

Diagrams Repository of diagrams made for articles on my blog. All diagrams are created using diagrams.net. UTF-8 Licenses Copyright 2022 Seth Michael

Seth Michael Larson 24 Aug 13, 2022
Image generation API.

Image Generator API This is an api im working on Currently its just a test project Im trying to make custom readme images with your discord account pr

Siddhesh Zantye 2 Feb 19, 2022
Convert photos to paintings with python

Convert-photos-to-paintings Before the changes After the changes Before the changes After the changes This code is written in the Python programming l

Amir Hussein Sharifnezhad 3 May 31, 2022
Program designed to mass edit and watermark all photos in a directory

Photographer-All-In-One This is a program designed for photographers to mass edit or watermark photos (.jpg || .png) You can run this program from any

Brad Martin 2 Nov 23, 2021
A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos.

font2png A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos. To use from command line it expects python3 to be at /

Rich Elmes 3 Dec 22, 2021
A small Python module for BMP image processing.

micropython-microbmp A small Python module for BMP image processing. It supports BMP image of 1/2/4/8/24-bit colour depth. Loading supports compressio

Quan Lin 4 Nov 02, 2022
An open source image editor which can manipulate an image in many ways!

Image Editor - An open source image editor which can manipulate an image in many ways! If you need any more modes in repo or I

TroJanzHEX 44 Nov 17, 2022
Nanosensor Image Processor (NanoImgPro), a python-based image analysis tool for dopamine nanosensors

NanoImgPro Nanosensor Image Processor (NanoImgPro), a python-based image analysis tool for dopamine nanosensors NanoImgPro.py contains the main class

1 Mar 02, 2022
Nudity detection with Python

nude.py About Nudity detection with Python. Port of nude.js to Python. Installation from pip: $ pip install --upgrade nudepy from easy_install: $ eas

Hideo Hattori 881 Jan 06, 2023
🎶😤 Generate an image indicating what you are listening to 😳

I'm Listening to This (song that I've sent you an image about detailing its metadata in a nifty way) Few lines describing your project. 📝 Table of Co

Connor B - Viibrant 4 Nov 03, 2021
【萝莉图片算法】高损图像压缩算法!?

【萝莉图片算法】高损图像压缩算法!? 我又发明出新算法了! 这次我发明的是新型高损图像压缩算法——萝莉图片算法!为什么是萝莉图片,这是因为它是使动用法,让图片变小所以是萝莉图片,大家一定要学好语文哦! 压缩效果 太神奇了!压缩率竟然高达99.97%! 与常见压缩算法对比 在图片最终大小为1KB的情况

黄巍 49 Oct 17, 2022