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
Simple AI app that is guessing color of apple in picture

Apple Color Determinant Application that is guessing color of apple from image Install Pillow, sklearn and numpy, using command for your package manag

Gleb Nikitin 1 Oct 25, 2021
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
A Gtk based Image Selector with Preview

gtk-image-selector This is an attempt to restore Gtk Image Chooser "lost functionality": displaying an image preview when selecting images... This is

Spiros Georgaras 2 Sep 28, 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
HCaptcha solver using requests and an image recognition package!

HCaptcha solver using requests and an image recognition package! Report Bug · Request Feature Features Image recognition Requests base

dropout 6 Oct 22, 2021
Easily turn large sets of image urls to an image dataset. Can download, resize and package 100M urls in 20h on one machine.

img2dataset Easily turn large sets of image urls to an image dataset. Can download, resize and package 100M urls in 20h on one machine. Also supports

Romain Beaumont 1.4k Jan 01, 2023
Console images in 48 colors, 216 colors and full rgb

console_images Console images in 48 colors, 216 colors and full rgb Full RGB 216 colors 48 colors If it does not work maybe you should change color_fu

Урядов Алексей 5 Oct 11, 2022
Me cleaner - Tool for partial deblobbing of Intel ME/TXE firmware images

me_cleaner me_cleaner is a Python script able to modify an Intel ME firmware image with the final purpose of reducing its ability to interact with the

Nicola Corna 4.1k Jan 08, 2023
MikuMikuRig是一款集生成控制器,自动导入动画,自动布料为一体的blender插件

Miku_Miku_Rig MikuMikuRig是一款集生成控制器,自动导入动画,自动布料为一体的blender插件。 MikumiKurig is a Blender plugin that can generates rig, automatically imports animations

小威廉伯爵 342 Dec 29, 2022
Vignette is a Python library to create and manage thumbnails following the FreeDesktop standard.

Vignette Vignette is a Python library to create and manage thumbnails following the FreeDesktop standard. Thumbnails are stored in a shared directory

3 Feb 06, 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
Python Interface of P3D

pyp3d 介绍: pyp3d是一个可在python上使用的工具包,它提供了一种可使用python脚本驱动创建模型的方法,为三维建模提供了全新的思路。 pyp3d中定义了一系列建模相关的必要的数据类型,例如球体、圆锥台、四棱锥台、 拉伸体、圆角管等几何体,pyp3d还提供了许多函数来实现放置集合体、

20 Sep 07, 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
Generate different types of random avatars.

avatar-generator Generate different types of random avatars. Requirements Python3 pytorch=1.6 cv2=3.4 tqdm 1. Github-like avatars python generate_gi

Ming 11 Apr 02, 2022
Python Digital Art Generator

Python Digital Art Generator The main goal of this repository is to generate all possible layers permutations given by the user in order to get unique

David Cuentas Mar 3 Mar 12, 2022
A Blender add-on to create interesting meshes using symmetry

Procedural Symmetries This Blender add-on automates the process of iteratively applying a set of reflection planes to a base mesh. The result will con

1 Dec 29, 2021
Fixes 500+ mislabeled MURA images

In this repository, new csv files are provided that fixes 500+ mislabeled MURA x-rays for all categories. The mislabeled x-rays mainly had hardware in them. This project only fixes the false negative

Pieter Zeilstra 4 May 18, 2022
【萝莉图片算法】高损图像压缩算法!?

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

黄巍 49 Oct 17, 2022
Convert Image to ASCII Art

Convert Image to ASCII Art Persiapan aplikasi ini menggunakan bahasa python dan beberapa package python. oleh karena itu harus menginstall python dan

Huda Damar 48 Dec 20, 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