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
A 3D structural engineering finite element library for Python.

An easy to use elastic 3D structural engineering finite element analysis library for Python.

Craig 220 Dec 27, 2022
Png2Jpg tool will help you convert from png image format to jpg images format.

PNG 2 JPG All codes assume running from root directory. Please update the sys path at the beginning of the codes before running. Over View Png2Jpg too

Nguyễn Trường Lâu 2 Dec 27, 2021
Image2scan - a python program that can be applied on an image in order to get a scan of it back

image2scan Purpose image2scan is a python program that can be applied on an image in order to get a scan of it back. For this purpose, it searches for

Kushal Shingote 2 Feb 13, 2022
Simple to use image handler for python sqlite3.

SQLite Image Handler Simple to use image handler for python sqlite3. Functions Function Name Parameters Returns init databasePath : str tableName : st

Mustafa Ozan Çetin 7 Sep 16, 2022
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
A tool to maintain an archive/mirror of your Google Photos library for backup purposes.

Google Photos Archiver Updated Instructions 8/9/2021 Version 2.0.6 Instructions: Download the script (exe or python script listed below) Follow the in

Nick Dawson 116 Jan 03, 2023
Napari simpleitk image processing

napari-simpleitk-image-processing (n-SimpleITK) Process images using SimpleITK in napari Usage Filters of this napari plugin can be found in the Tools

Robert Haase 11 Dec 19, 2022
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 0 Oct 18, 2022
Computer art based on quadtrees.

Quads Computer art based on quadtrees. The program targets an input image. The input image is split into four quadrants. Each quadrant is assigned an

Michael Fogleman 1.1k Dec 23, 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
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
💯 Watermark your images with one line of command

Watermarker 💯 Watermark your images with one line of command 🧐 $ pip3 install

Orhan Emre Dikicigil 3 May 01, 2022
MetaStalk is a tool that can be used to generate graphs from the metadata of JPEG, TIFF, and HEIC images

MetaStalk About MetaStalk is a tool that can be used to generate graphs from the metadata of JPEG, TIFF, and HEIC images, which are tested. More forma

Cyb3r Jak3 1 Jul 05, 2021
Small wrapper around 3dmol.js and html2canvas for creating self-contained HTML files that display a 3D molecular representation.

Description Small wrapper around 3dmol.js and html2canvas for creating self-contained HTML files that display a 3D molecular representation. Double cl

David Meijer 1 Dec 02, 2021
🛹 Turn an SVG into an STL for stencil creation purposes

svg2stl This repository provides a script which takes as input an SVG such as this one: It outputs an STL file like this one: You can also see an inte

Max Halford 3 Dec 29, 2021
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
python binding for libvips using cffi

README PyPI package: https://pypi.python.org/pypi/pyvips conda package: https://anaconda.org/conda-forge/pyvips We have formatted docs online here: ht

libvips 467 Dec 30, 2022
Bringing vtk.js into Dash and Python

Dash VTK Dash VTK lets you integrate the vtk.js visualization pipeline directly into your Dash app. It is powered by react-vtk-js. Docs Demo Explorer

Plotly 88 Nov 29, 2022
With this simple py script you will be able to get all the .png from a folder and generate a yml for Oraxen

Oraxen-item-to-yml With this simple py script you will be able to get all the .png from a folder and generate a yml for Oraxen How to use Install the

Akex 1 Dec 29, 2021
Qrgenerator - A qr generator app using python3

qrgenerator by Mal4D Hi welcome into qr code generator using python by Mal4d Lin

Mal4D 1 Jan 09, 2022