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
Craft PNG files that appear completely different in Apple software

Ambiguous PNG Packer Craft PNG files that appear completely different in Apple software

David Buchanan 1k Dec 29, 2022
display: a browser-based graphics server

display: a browser-based graphics server Installation Quick Start Usage Development A very lightweight display server for Torch. Best used as a remote

Szymon Jakubczak 205 Oct 17, 2022
An API that renders HTML/CSS content to PNG using Chromium

html_png An API that renders HTML/CSS content to PNG using Chromium Disclaimer I am not responsible if you happen to make your own instance of this AP

10 Aug 08, 2022
Art directed cropping, useful for responsive images

Art direction sets a focal point and can be used when you need multiple copies of the same Image but also in in different proportions.

Daniel 1 Aug 16, 2022
TRREASURE_IMAGE is python lib by which you can hide anything in a .jpg image with Command-Line Interface[cli] feature

TRREASURE_IMAGE TRREASURE_IMAGE is a python third-party library with Command-Line Interface[cli] feature. Table of Contents General Info Python librar

Fatin Shadab 3 Jun 07, 2022
Magic-Square - Creates a magic square by randomly generating a list until the list happens to be a magic square

Magic-Square Creates a magic square by randomly generating a list until the list happens to be a magic square. Done as simply as possible... Frequentl

Nick 2 Jan 01, 2022
Deep Illuminator is a data augmentation tool designed for image relighting.

Deep Illuminator Deep Illuminator is a data augmentation tool designed for image relighting. It can be used to easily and efficiently genera

George Chogovadze 52 Nov 29, 2022
Multiparametric Image Analysis

Documentation The documentation is available on populse_mia's website here Installation From PyPI, for users By cloning the package, for developers Fr

Populse 9 Dec 14, 2022
hashmask reverse lookup

ImageHashMasks Lookup Hashmask NFT index from a picture Setup pip install pillow click imagehash Usage $ python imagehashmasks.py

17 Nov 29, 2021
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
Archive of the image generator stuff from my API

alex_api_archive Archive of the image generator stuff from my API FAQ Q: Why? A: Because I am removing these components from the API Q: How do I run i

AlexFlipnote 26 Nov 17, 2022
image-processing exercises.

image_processing Assignment 21 Checkered Board Create a chess table using numpy and opencv. view: Color Correction Reverse black and white colors with

Benyamin Zojaji 25 Dec 15, 2022
DrawBot is a powerful, free application for macOS that invites you to write Python scripts to generate two-dimensional graphics

DrawBot is a powerful, free application for macOS that invites you to write Python scripts to generate two-dimensional graphics.

Frederik Berlaen 344 Jan 06, 2023
This projects aim is to simulate flowers(Gerbera Daisy) phyllotaxis.

phyllotaxis This projects aim is to simulate flowers(Gerbera Daisy) phyllotaxis. Take a look at the arrangement of this flower's seeds, this project's

amirsalar 3 Dec 10, 2021
Samila is a generative art generator written in Python

Samila is a generative art generator written in Python, Samila let's you create arts based on many thousand points. The position of every single point is calculated by a formula, which has random par

Sepand Haghighi 947 Dec 30, 2022
A utility for quickly cropping large collections of images.

Crop Tool A utility for quickly cropping large collections of images. Inspired by Derrick Schultz's dataset-tools. Setup It's suggested that you use A

dusk (they/them) 6 Nov 14, 2021
Depix is a tool for recovering passwords from pixelized screenshots.

This implementation works on pixelized images that were created with a linear box filter. In this article I cover background information on pixelization and similar research.

23.1k Jan 04, 2023
Program to export all new icons from the latest Fortnite patch

Assets Exporter This program allows you to generate all new icons of a patch in png! Requierements Python =3.8 (installed on your computer) If you wa

ᴅᴊʟᴏʀ3xᴢᴏ 6 Jun 24, 2022
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
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