Easy to use Python module to extract Exif metadata from digital image files.

Overview

EXIF.py

https://travis-ci.org/ianare/exif-py.png

Easy to use Python module to extract Exif metadata from digital image files.

Supported formats: TIFF, JPEG, Webp, HEIC

Compatibility

EXIF.py is tested and officially supported on the following Python versions:

  • 3.5
  • 3.6
  • 3.7
  • 3.8

Starting with version 3.0.0, Python2 compatibility is dropped completely (syntax errors due to type hinting).

https://pythonclock.org/

Installation

PyPI

The recommended process is to install the PyPI package, as it allows easily staying up to date:

$ pip install exifread

See the pip documentation for more info.

Archive

Download an archive from the project's releases page.

Extract and enjoy.

Usage

Command line

Some examples:

$ EXIF.py image1.jpg
$ EXIF.py -dc image1.jpg image2.tiff
$ find ~/Pictures -name "*.jpg" -o -name "*.tiff" | xargs EXIF.py

Show command line options:

$ EXIF.py -h

Python Script

import exifread
# Open image file for reading (must be in binary mode)
f = open(path_name, 'rb')

# Return Exif tags
tags = exifread.process_file(f)

Note: To use this library in your project as a Git submodule, you should:

from 
   import exifread

 

Returned tags will be a dictionary mapping names of Exif tags to their values in the file named by path_name. You can process the tags as you wish. In particular, you can iterate through all the tags with:

for tag in tags.keys():
    if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'):
        print "Key: %s, value %s" % (tag, tags[tag])

An if statement is used to avoid printing out a few of the tags that tend to be long or boring.

The tags dictionary will include keys for all of the usual Exif tags, and will also include keys for Makernotes used by some cameras, for which we have a good specification.

Note that the dictionary keys are the IFD name followed by the tag name. For example:

'EXIF DateTimeOriginal', 'Image Orientation', 'MakerNote FocusMode'

Tag Descriptions

Tags are divided into these main categories:

  • Image: information related to the main image (IFD0 of the Exif data).
  • Thumbnail: information related to the thumbnail image, if present (IFD1 of the Exif data).
  • EXIF: Exif information (sub-IFD).
  • GPS: GPS information (sub-IFD).
  • Interoperability: Interoperability information (sub-IFD).
  • MakerNote: Manufacturer specific information. There are no official published references for these tags.

Processing Options

These options can be used both in command line mode and within a script.

Faster Processing

Don't process makernote tags, don't extract the thumbnail image (if any).

Pass the -q or --quick command line arguments, or as:

tags = exifread.process_file(f, details=False)

Stop at a Given Tag

To stop processing the file after a specified tag is retrieved.

Pass the -t TAG or --stop-tag TAG argument, or as:

tags = exifread.process_file(f, stop_tag='TAG')

where TAG is a valid tag name, ex 'DateTimeOriginal'.

The two above options are useful to speed up processing of large numbers of files.

Strict Processing

Return an error on invalid tags instead of silently ignoring.

Pass the -s or --strict argument, or as:

tags = exifread.process_file(f, strict=True)

Usage Example

This example shows how to use the library to correct the orientation of an image (using Pillow for the transformation) before e.g. displaying it.

import exifread
from PIL import Image
import logging

def _read_img_and_correct_exif_orientation(path):
    im = Image.open(path)
    tags = {}
    with open(path, 'rb') as f:
        tags = exifread.process_file(f, details=False)
    if "Image Orientation" in tags.keys():
        orientation = tags["Image Orientation"]
        logging.basicConfig(level=logging.DEBUG)
        logging.debug("Orientation: %s (%s)", orientation, orientation.values)
        val = orientation.values
        if 5 in val:
            val += [4,8]
        if 7 in val:
            val += [4, 6]
        if 3 in val:
            logging.debug("Rotating by 180 degrees.")
            im = im.transpose(Image.ROTATE_180)
        if 4 in val:
            logging.debug("Mirroring horizontally.")
            im = im.transpose(Image.FLIP_TOP_BOTTOM)
        if 6 in val:
            logging.debug("Rotating by 270 degrees.")
            im = im.transpose(Image.ROTATE_270)
        if 8 in val:
            logging.debug("Rotating by 90 degrees.")
            im = im.transpose(Image.ROTATE_90)
    return im

Credit

A huge thanks to all the contributors over the years!

Originally written by Gene Cash & Thierry Bousch.

Comments
  • exifread reaturn empty tags object

    exifread reaturn empty tags object

    Hi,

    I tried your ExifRead on my Synology on two different images, that both contain tags if read with exiftool.

    What details can I provide you?

    Linux Synology_NAS 3.2.40 #3810 SMP Wed Nov 6 05:13:41 CST 2013 armv7l GNU/Linux synology_armadaxp_ds214+

    Python 3.3.2 (default, Dec 23 2013, 16:12:02) [GCC 4.6.4] on linux

    EXIF.py Ver 1.4.2

    BR Nippey

    bug 
    opened by Nippey 21
  • Python 3 support?

    Python 3 support?

    I whacked at it until it seems to run under Python 3, but I didn't make the code conditional, so I have a replacement version... any interest? I'm not a git user, so I just grabbed the file, and edited. Tell me where to email the file, if interested. Was pretty straightforward. Otherwise I'll just put it on my web site, and it will acquire bit-rot...

    My goal was to extract GPS data, so I added --gps option to print only that.

    opened by v-python 12
  • Module not installing on Python 3.3.

    Module not installing on Python 3.3.

    Seems imports are at fault, the path for makernote* is not automatically found when module is being installed. I modified the imports so that they work. Tested to be working on Python 2.7 and 3.3.

    bug enhancement 
    opened by velis74 11
  • Testing the library

    Testing the library

    I recently forked the project here: https://github.com/rshk/exif-py/ and started some refactoring/clean up (pull requests coming soon), in order to make it installable from pypi and more efficient / maintainable.

    I was wondering: what do you use for testing? Do you have a collection of jpegs along with known tag data? The library is seriously missing some unittests; I'd like to write some, but I miss the data..

    enhancement 
    opened by rshk 10
  • Correcty process the Makernote of some Canon models

    Correcty process the Makernote of some Canon models

    Needed to correctly process Makernote of some Canon cameras. For instance Canon Powershot SX60.

    After this pull request is accepted, I have two more about HDR tags.

    opened by jcea 9
  • Why more accuracy from OSX's

    Why more accuracy from OSX's "Preview" application?

    For a particular image, exif-py tells me the latitude is:

    EXIF GPS GPSLatitude, [31, 27, 2147/100]

    So 31 degrees, 27 minutes, 21.47 seconds.

    But if I view the GPS info from Preview in OSX, it tells me 21.468 seconds. An additional digit of accuracy.

    Can you help me understand why?

    Image and screenshot of exif-py and preview attached.

    why_more_accurate img_0234

    question 
    opened by bitwombat 8
  • Update reconyx

    Update reconyx

    Add reconyx makernote tag mapping file for hc500 hyperfire, ultrafire and hf2 pro cameras. Ported from https://fossies.org/linux/Image-ExifTool/lib/Image/ExifTool/Reconyx.pm. Currently untested.

    stubbed out 'cryptic_maker_note' method in classes.py since these images don't contain a 'make' tag in the exif data. Currently it's hard-wired to assume 'reconyx' make, but probably would be better to make it more generic. Not sure how many cameras have this same issue.

    opened by parappathekappa 7
  • Fix MemoryError when string is large

    Fix MemoryError when string is large

    If a large string is read in then calling values.split caused a MemoryError. Even if that is caught, the python internal state became unusable. This patch avoids the problem by only reading up to the null byte.

    opened by richq 7
  • TypeError: unsupported operand type(s) for +: 'int' and 'str'

    TypeError: unsupported operand type(s) for +: 'int' and 'str'

    I was processing a large list of image files and I was getting the error 'TypeError: unsupported operand type(s) for +: 'int' and 'str''. This is the complete output:

    Opening: /Users/familypc/Desktop/culprit.jpg
    Traceback (most recent call last):
      File "./EXIF.py", line 132, in <module>
        main()
      File "./EXIF.py", line 100, in main
        data = process_file(file, stop_tag=stop_tag, details=detailed, strict=strict, debug=debug)
      File "/private/tmp/exif-py/exifread/__init__.py", line 201, in process_file
        hdr.dump_IFD(exif_off.values[0], 'EXIF', stop_tag=stop_tag)
      File "/private/tmp/exif-py/exifread/classes.py", line 124, in dump_IFD
        entries = self.s2n(ifd, 2)
      File "/private/tmp/exif-py/exifread/classes.py", line 71, in s2n
        self.file.seek(self.offset + offset)
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    

    I was able to track the issue to a particular file: culprit

    That file was an Photoshop export from a Nikon RAW image (*.nef) to jpg. I don't know what's wrong with it. I have other files exported the same way and I didn't have issues. The files is perfectly fine because I can open it.

    bug 
    opened by fjgonzalezm 6
  • Using setuptools and changed way versioning is done

    Using setuptools and changed way versioning is done

    Hi Ianare,

    i saw that you have already included some of the modification i did on my fork of your exif-py. I merged those back to my fork and did a few more modification, which i put in this pull request. I hope i did it right, since i'm still more accustomed to svn than to git. I did not change too much:

    • i switched from distutils to setuptool and made the EXIF.py script an entry point insteat of a script
    • the version number is now in exifread.init and is imported in both the setup.py and the EXIF.py to use with the -v switch

    I have a few more things in mind so you can expect some more pull requests if this one works as expected.

    Regards, Peter

    opened by peterreimer 4
  • python3.2.3 support

    python3.2.3 support

    Hi, First thanks for the excellent work. I'm trying to use this with Python 3.2.3 and have run across some issues.

    1. In order to get the if to work for detecting the file type I had to change if data[base:base+2]=='\xFF\xE1': to if data[base:base+2]==b'\xFF\xE1': Adding a b binary flag (this also was fine when running with python2.7
    2. Issue with ord() i.e. File "EXIF.py", line 1691, in process_file base=base+ord(data[base+2])*256+ord(data[base+3])+2 TypeError: ord() expected string of length 1, but int found I think if the ord() calls are removed (no convert needed) this fixes it for python3.2.3 (but will have issues on 2.7).
    3. It then fails at the following (data[base:base+2] is empty): Segment base 0xCAD0 Unexpected/unhandled segment type or file content.

    It would be excellent to have this working for Python 3.2.3 if possible. Works excellently with 2.7. Many thanks.

    enhancement 
    opened by meltwater2000 4
  • str/bytes problems

    str/bytes problems

    While writing type stubs for ExifRead (python/typeshed#9403), I've come across a few inconsistencies/bugs that are probably related to the str/bytes changes from Python 2 to Python 3.

    1. ord_ is only ever called with a bytes argument, but checks for a str and returns a bytes argument unchanged:

    https://github.com/ianare/exif-py/blob/51d5c5adf638219632dd755c6b7a4ce2535ada62/exifread/utils.py#L9-L12

    I believe this method is mostly obsolete and could be replaced by straight calls to ord().

    1. special_mode() in tags/makernote/olympus.py is (I think) passed a bytes string and returns a regular str. But in the case where the passed in string is empty, it will just return it unchanged (i.e. it will return bytes instead of str), possibly raise a TypeError:

    https://github.com/ianare/exif-py/blob/51d5c5adf638219632dd755c6b7a4ce2535ada62/exifread/tags/makernote/olympus.py#L5-L26

    opened by srittau 0
  • HEIC + iPhone: ignore heic boxes

    HEIC + iPhone: ignore heic boxes

    Not sure if this was the intended behavior here as get_parser has no flow to return None, however, this change worked for me to load iPhone files, hoping it's helpful for someone else.

    opened by Knio 0
  • Allow extract thumbnail with details=False

    Allow extract thumbnail with details=False

    With this simple modification, it is possible to use details=False, extract_thumbnail=True. Processing 1156 CR2 images on a SD card-on USB card reader takes: details=True, extract_thumbnail=True (204 s) details=True, extract_thumbnail=True (2.67 s) details=False, extract_thumbnail=True (2.67 s)

    So thumbnail extraction is very fast and should be possible to allow it independent of the detailed tags.

    opened by angel6700 0
  • Fix endianess bug while reading DJI makernotes, add Make tag

    Fix endianess bug while reading DJI makernotes, add Make tag

    As the title says, while testing more images I found that some files use Motorola endian but DJI's makernotes always seem to be in Intel endian (like for Fujifilm makernotes).

    This PR fixes that.

    opened by pierotofy 0
  • Many useless warnings

    Many useless warnings

    I am opening many image file and see absolutely useless warning:

    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    PNG file does not have exif data.
    

    module version:

    $ pip3 list | grep ExifRead
    ExifRead                3.0.0
    

    If image file does not have exif data we just get empty dict.

    opened by MichaelMonashev 2
  • Fix reading for long MakerNote and UserComment

    Fix reading for long MakerNote and UserComment

    Top-level large entries (e.g. MakerNote and UserComment) are usually in data format 7 (unspecified). See: http://www.fifi.org/doc/jhead/exif-e.html#DataForm We should simply ignore its length, read and keep its original values for further use.

    But IfdTag entries inside MakerNote still have problems, which requires further investigation.

    opened by Lessica 0
Releases(3.0.0)
  • 3.0.0(May 8, 2022)

    • BREAKING CHANGE: Add type hints, which removes Python2 compatibility
    • Update make_string util to clean up bad values (#128) by Étienne Pelletier
    • Fix Olympus SpecialMode Unknown Values (#143) by Paul Barton
    • Remove coding system from UserComment sequence only if it is valid (#147) by Grzegorz Ruciński
    • Fixes to orientation by Mark
    • Add some EXIF tags
    • Add support for PNG files (#159) by Marco
    • Fix for HEIC Unknown Parsers (#153) by Paul Barton
    • Handle images that has corrupted headers/tags (#152) by Mahmoud Harmouch
    Source code(tar.gz)
    Source code(zip)
  • 2.3.2(Oct 29, 2020)

  • 2.3.1(Aug 7, 2020)

  • 2.3.0(Aug 3, 2020)

    • Add notice on Python2 EOL
    • Modernize code and improve testing, split up some huge functions
    • Added support for webp file format (#116) by Grzegorz Ruciński
    • Add linting
    • Added missing IFD data type; correct spelling mistake (#119) by Piero Toffanin
    • Add syntax highlight for README (#117) by John Lin
    • Add Python 3.8 to CI (#113) by 2*yo
    • make HEIC exif extractor much more compatible (#109) by Tony Guo
    • Add black level tag (#108)
    • Use list instead of tuple for classifiers (#107) by Florian Preinstorfer
    Source code(tar.gz)
    Source code(zip)
  • 2.2.1(Jul 31, 2020)

  • 2.2.0(Jul 30, 2020)

    • Add support for Python 3.5, 3.6, 3.7
    • Drop official support for Python 2.6, 3.2, 3.3
    • Fix for string count equals 0 (issue #67)
    • Rebasing of struct pull requests: closes #54, closes #60 (Christopher Chavez)
    • Raw images support by changing Tiff detection (xaumex)
    • Fix GPS information erroneously None #96 (Christopher Chavez)
    • Initial HEIC support (Sam Rushing)
    Source code(tar.gz)
    Source code(zip)
Owner
ianaré sévi
I'm an alligator. Roôar.
ianaré sévi
HtmlWebShot - A python3 package which Can Create Images From url, Html-CSS, Svg and from any readable file and texts with many setup features.

A python3 package which Can Create Images From url, Html-CSS, Svg and from any readable file and texts with many setup features

Danish 24 Dec 14, 2022
QR-code Generator with a basic GUI.

Qr_generator_python Qr code generator with a basic GUI. ❔ About the QR-Code-Generator This project Generates QR codes to sites, e-mails and plain text

Tecixck 2 Oct 11, 2021
Validate arbitrary image uploads from incoming data urls while preserving file integrity but removing EXIF and unwanted artifacts and RCE exploit potential

Validate arbitrary base64-encoded image uploads as incoming data urls while preserving image integrity but removing EXIF and unwanted artifacts and mitigating RCE-exploit potential.

A3R0 1 Jan 10, 2022
A proof-of-concept implementation of a parallel-decodable PNG format

mtpng A parallelized PNG encoder in Rust by Brion Vibber [email protected] Backgrou

Brion Vibber 193 Dec 16, 2022
Pythonocc nodes for Ryven

Pythonocc-nodes-for-Ryven Pythonocc nodes for Ryven Here a way to work on Pythonocc with a node editor, Ryven in that case. To get it functional you w

Tanneguy 30 Dec 18, 2022
impy is an all-in-one image analysis library, equipped with parallel processing, GPU support, GUI based tools and so on.

impy is All You Need in Image Analysis impy is an all-in-one image analysis library, equipped with parallel processing, GPU support, GUI based tools a

24 Dec 20, 2022
Avatar Generator Python

This is a simple avatar generator project which uses your webcam to take pictures and saves five different types of your images into your device including the original image.

Faisal Ahmed 3 Jan 23, 2022
A collection of python scripts which help you programatically create PNGs or GIFs

A collection of python scripts which help you programatically create PNGs or GIFs and their Metadata in bulk with custom rarity rates, upload them to OpenSea & list them for sale.

Tom 30 Dec 24, 2022
Quickly 'anonymize' all people in an image. This script will put a black bar over all eye-pairs in an image

Face-Detacher Quickly 'anonymize' all people in an image. This script will put a black bar over all eye-pairs in an image This is a small python scrip

Don Cato 1 Oct 29, 2021
Qt based ebook reader

Qt based ebook reader Currently supports: pdf epub djvu fb2 mobi azw / azw3 / azw4 cbr / cbz md Contribute Paypal Bitcoin: 17jaxj26vFJNqQ2hEVerbBV5fpT

1.4k Dec 26, 2022
Gbs-image-colorizer - A tool to convert colorful pictures to GB Studio-compatible colorized backgrounds.

GB Studio Image Colorizer A tool to convert colorful pictures to GB Studio-compatible colorized backgrounds. Made by NalaFala/Yousurname/Y0UR-U5ERNAME

Yousurname 8 Dec 08, 2022
Sample data for the napari image viewer.

napari-demo-data Sample data for the napari image viewer. This napari plugin was generated with Cookiecutter using @napari's cookiecutter-napari-plugi

Genevieve Buckley 1 Nov 08, 2021
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
ModernGL is a python wrapper over OpenGL 3.3+ core

ModernGL is a python wrapper over OpenGL 3.3+ core that simplifies the creation of simple graphics applications like scientific simulations, games or user interface

ModernGL 1.4k Jan 01, 2023
Conversion of Image, video, text into ASCII format

asciju Python package that converts image to ascii Free software: MIT license

Aju Tamang 11 Aug 22, 2022
Manipulate EXIF and IFD metadata.

Tyf Copyright Distribution Support this project Buy Ѧ and: Send Ѧ to AUahWfkfr5J4tYakugRbfow7RWVTK35GPW Vote arky on Ark blockchain and earn Ѧ weekly

16 Jan 21, 2022
This is the official source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.

Freedom to build what you want FreeCAD is an open-source parametric 3D modeler made primarily to design real-life objects of any size. Parametric modeling allows you to easily modify your design by g

FreeCAD 12.9k Jan 07, 2023
pix2tex: Using a ViT to convert images of equations into LaTeX code.

The goal of this project is to create a learning based system that takes an image of a math formula and returns corresponding LaTeX code.

Lukas Blecher 2.6k Dec 30, 2022
Graphical tool to make photo collage posters

PhotoCollage Graphical tool to make photo collage posters PhotoCollage allows you to create photo collage posters. It assembles the input photographs

Adrien Vergé 350 Jan 02, 2023
Simple Python package to convert an image into a quantized image using a customizable palette

Simple Python package to convert an image into a quantized image using a customizable palette. Resulting image can be displayed by ePaper displays such as Waveshare displays.

Luis Obis 3 Apr 13, 2022