How to extract metadata from an image using python?
Asked Answered
F

5

38

How can I extract metadata from an image using Python?

Furlana answered 11/2, 2014 at 9:20 Comment(5)
Python does not have a standard module for accessing image metadata. You will need to search for a module that provides such functionality for the formats you're interested in.Lemmon
What metadata do you want?Capacity
i think answer is available at #765896Choker
The answer is there, but it is somewhat dated, and since the topic you link to is closed, it can't be updated. Several of the projects mentioned in that topic are dead or moribund.Pooka
Does this answer your question? In Python, how do I read the exif data for an image?Euton
P
44

Use Pillow, it's a fork of PIL that is still in active development, and supports python3. Here I use a dict generator to map the exif data to a dict

from PIL import Image, ExifTags
img = Image.open("/path/to/file.jpg")
exif = { ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS }
Pooka answered 11/2, 2014 at 9:38 Comment(8)
For PNG images you can access the metadata by reading the info dictionary of the img variable. I posted the same answer here: #48632408Quadrivial
it gives me that error: metadata = { ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS } builtins.AttributeError: 'NoneType' object has no attribute 'items' Alcock
It's possible that you have an image without exif dataPooka
@Pooka This method works but it does not give all the metadata as Focal lenght. When you see the properties of the image by right clicking it you can see all details but using this you can just get an output as the following: ImageWidth : 4128 ImageLength : 3096 ResolutionUnit : 2 ExifOffset : 225 Make : mchn Model : yyy Software : xxx Orientation : 6 YCbCrPositioning : 1 DateTime : ddtt XResolution : 72.0 YResolution : 72.0Gamogenesis
@Gamogenesis Cameras record different metadata tags. Are you sure the focal length was in the metadata captured by the camera?Technicolor
@Quadrivial Your solution was the simplest solution that actually worked for me.Helio
Funny that a 10 year old solution still worksPooka
img._getexif() can return None so need if img._getexif() else {} at end of lineCabral
I
20

There is couple of ways by which you can get the data from the file.

1. using Exif tool :

for Windows and mac: it is available at ExifTool for linux : You can install ExifTool on Ubuntu using the apt utility sudo apt install libimage-exiftool-perl

You can now run ExifTool anywhere in your terminal by typing exiftool. This is recommended approach to get the meta data as it gives more tags than any other way. It is a command line tool and to use it in Python user have to create a subprocess and pass the tool and image file path as an argument. Please refer the below code snippet to get the meta data using exif tool. (

infoDict = {} #Creating the dict to get the metadata tags
exifToolPath = 'D:/ExifTool/exifTool.exe' #for Windows user have to specify the Exif tool exe path for metadata extraction. 
#For mac and linux user it is just 
 """exifToolPath = exiftool"""
imgPath = 'D:/Images/12.jpg'

''' use Exif tool to get the metadata '''
process = subprocess.Popen([exifToolPath,imgPath],stdout=subprocess.PIPE, stderr=subprocess.STDOUT,universal_newlines=True) 
''' get the tags in dict '''
for tag in process.stdout:
    line = tag.strip().split(':')
    infoDict[line[0].strip()] = line[-1].strip()

for k,v in infoDict.items():
    print(k,':', v)

Metadata Result for below image:

enter image description here

enter image description here

Full Tag list is here:

""" ExifTool Version Number : 11.63
File Name : imgMeta.jpg
Directory : /Projects/ImageMetaData/Images
File Size : 32 kB
File Modification Date/Time : 30
File Access Date/Time : 30
File Creation Date/Time : 30
File Permissions : rw-rw-rw-
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Exif Byte Order : Little-endian (Intel, II)
Make : Canon
Camera Model Name : Canon PowerShot S40
Orientation : Horizontal (normal)
X Resolution : 180
Y Resolution : 180
Resolution Unit : inches
Modify Date : 44
Y Cb Cr Positioning : Centered
Exposure Time : 1/500
F Number : 4.9
Exif Version : 0220
Date/Time Original : 44
Create Date : 44
Components Configuration : Y, Cb, Cr, -
Compressed Bits Per Pixel : 5
Shutter Speed Value : 1/501
Aperture Value : 5.0
Max Aperture Value : 2.8
Flash : Auto, Did not fire
Focal Length : 103.7 mm)
Macro Mode : Normal
Self Timer : Off
Quality : Superfine
Canon Flash Mode : Auto
Continuous Drive : Single
Focus Mode : Single
Record Mode : JPEG
Canon Image Size : Large
Easy Mode : Manual
Digital Zoom : None
Contrast : Normal
Saturation : Normal
Sharpness : 0
Camera ISO : 100
Metering Mode : Center-weighted average
Focus Range : Auto
AF Point : Center
Canon Exposure Mode : Program AE
Lens Type : n/a
Max Focal Length : 21.3125 mm
Min Focal Length : 7.09375 mm
Focal Units : 32/mm
Max Aperture : 5
Min Aperture : 8
Flash Activity : 0
Flash Bits : (none)
Focus Continuous : Single
AE Setting : Normal AE
Display Aperture : 4.9
Zoom Source Width : 2272
Zoom Target Width : 2272
Spot Metering Mode : AF Point
Focal Type : Zoom
Focal Plane X Size : 7.26 mm
Focal Plane Y Size : 5.46 mm
Auto ISO : 100
Base ISO : 100
Measured EV : 13.63
Target Aperture : 5
Target Exposure Time : 1/501
Exposure Compensation : 0
White Balance : Auto
Slow Shutter : Off
Shot Number In Continuous Burst : 0
Optical Zoom Code : 6
Flash Guide Number : 0
AF Points In Focus : Center
Flash Exposure Compensation : 0
Auto Exposure Bracketing : Off
AEB Bracket Value : 0
Control Mode : Camera Local Control
Focus Distance Upper : 7.82 m
Focus Distance Lower : 0 m
Bulb Duration : 0
Camera Type : Compact
Canon Image Type : PowerShot S40 JPEG
Canon Firmware Version : Firmware Version 1.10
File Number : 117-1771
Owner Name : Andreas Huggel
Canon Model ID : PowerShot S40
User Comment : 
Flashpix Version : 0100
Color Space : sRGB
Exif Image Width : 2272
Exif Image Height : 1704
Interoperability Index : R98 - DCF basic file (sRGB)
Interoperability Version : 0100
Related Image Width : 2272
Related Image Height : 1704
Focal Plane X Resolution : 8114.285714
Focal Plane Y Resolution : 8114.285714
Focal Plane Resolution Unit : inches
Sensing Method : One-chip color area
File Source : Digital Camera
Custom Rendered : Normal
Exposure Mode : Auto
Digital Zoom Ratio : 1
Scene Capture Type : Standard
Compression : JPEG (old-style)
Thumbnail Offset : 2066
Thumbnail Length : 5448
Image Width : 480
Image Height : 360
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : 0 (2 2)
Drive Mode : Single-frame Shooting
ISO : 100
Lens : 34.5 - 103.7 mm)
Shooting Mode : Program AE
Aperture : 4.9
Image Size : 480x360
Lens ID : Unknown 7-21mm
Megapixels : 0.173
Scale Factor To 35 mm Equivalent : 4.9
Shutter Speed : 1/500
Thumbnail Image : (Binary data 5448 bytes, use -b option to extract)
Circle Of Confusion : 0.006 mm
Depth Of Field : 2.17 m (3.11 - 5.28 m)
Field Of View : 19.7 deg
Hyperfocal Distance : 15.02 m
Light Value : 13.6 """

2. using PIL package :

Refer any of the other post for this method. However the drawback of using this method is it doesn't works with all the images.

3. using hachoir package : Similar to exif tool, it is also a command line tool except that it's a python package
and user can install it using pip install hachoir. It can give metadata for most of the file formats but gives less information than Exif tool.

imgPath = 'D:/Images/12.jpg'
exeProcess = "hachoir-metadata"
process = subprocess.Popen([exeProcess,imgPath],
                                           stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                           universal_newlines=True)

for tag in process.stdout:
        line = tag.strip().split(':')
        infoDict[line[0].strip()] = line[-1].strip()

for k,v in infoDict.items():
    print(k,':', v)

"""for same image : only 31 tags are identified by hachoir Method however Exif method is giving 131 tags """

enter image description here

Full tag list extracted by hachoir is below :

""" Metadata : 
Image width : 480 pixels
Image height : 360 pixels
Image orientation : Horizontal (normal)
Bits/pixel : 24
Pixel format : YCbCr
Image DPI width : 72 DPI
Image DPI height : 72 DPI
Creation date : 44
Camera aperture : 2.97
Camera focal : 4.9
Camera exposure : 1/500
Camera model : Canon PowerShot S40
Camera manufacturer : Canon
Compression : JPEG (Baseline)
Thumbnail size : 5448 bytes
EXIF version : 0220
Date-time original : 44
Date-time digitized : 44
Compressed bits per pixel : 5
Shutter speed : 8.97
Aperture : 4.66
Exposure bias : 0
Focal length : 21.3
Flashpix version : 0100
Focal plane width : 8.11e+03
Focal plane height : 8.11e+03
Comment : 75%
Format version : JFIF 1.01
MIME type : image/jpeg
Endianness : Big endian
"""
Interested answered 23/8, 2019 at 6:50 Comment(7)
For PIL based method you commented: "drawback of this method is it works only with image and doesn't provide the metadata information for all the images".... What does that even mean ? Can you elaborate ?Chism
How do i extract the thumbnail image from this?Oeuvre
Using PIL for tags extraction doesn't work with all the images.Interested
Option 1 (exif-tool) is the only one that had the tags I need. But on Windows, the tool was hanging waiting for me to hit enter. I was able to overcome this by using the custom exif tool class in the top answer here: #10075615Iredale
@FebinSunny PIL based method do not extract info from png imagesWinifield
@majidbhatti yeah... would have been new info to me 4 YEARS ago...Chism
I was looking for alternatives @FebinSunny, yet it seems there does not have one.Winifield
O
10

You can extract metadata with PIL Exif library for Python :

from PIL import Image
from PIL.ExifTags import TAGS

After you can pass the image file path to open the image and read data of corresponding exif tags :

# path to the image or video
imagename = "IMG_20220306_095310.jpg"

# read the image data using PIL
image = Image.open(imagename)

# extract EXIF data
exifdata = image.getexif()

# iterating over all EXIF data fields
for tag_id in exifdata:
    # get the tag name, instead of human unreadable tag id
    tag = TAGS.get(tag_id, tag_id)
    data = exifdata.get(tag_id).decode("utf-16")
    print(f"{tag:25}: {data}")  
Orran answered 20/3, 2022 at 13:2 Comment(2)
Your method returns the utf-16 encoding. I was able to decode using : https://mcmap.net/q/410657/-how-to-convert-quot-b-39-xfe-xff-x002-x000-x001-x009-39-quot-to-character-in-pythonVia
Thank you that's right @bonzoon, I understand why in some cases and some tags there's an encoding :) I add the deconding function in my code ty againOrran
L
4

You can use following python code for this.

#!/bin/python
import os
import sys
from PIL import Image
from PIL.ExifTags import TAGS

image = sys.argv[1]

for (tag,value) in Image.open(image)._getexif().iteritems():
        print '%s = %s' % (TAGS.get(tag), value)

Here is the sample output. enter image description here

Lareine answered 9/5, 2018 at 14:29 Comment(3)
This is literally a copy of the other answerPooka
How do i extract the thumbnail information? and save it as an image?Oeuvre
I don't know why, maybe it's me but it worked for .JPG files but not .jpgTelega
I
2

some camera manufacturers add XMP data to images, and that data can be read easily with libxmp (pip install python-xmp-toolkit). I wrote a function to extract data from DJI drone images:

from libxmp.utils import file_to_dict

def read_xmp_data(image_path: Path):
    xmp_dict = file_to_dict(str(image_path))
    exif_dict = {}
    dji_data = {}

    # debug printout - helped me to find tag keywords in 'purl.org' 
    print(k)         

    for k in xmp_dict.keys():
        if 'drone-dji' in k:
            for element in xmp_dict[k]:
                dji_data[element[0].replace('drone-dji:', '')] = element[1]
        if 'exif' in k:
            for element in xmp_dict[k]:
                exif_dict[element[0].replace('exif:', '')] = element[1]
    return dji_data, exif_dict

read_xmp_data("image.jpg")

A remark from editor: python-xmp-toolkit was released in 2014 and it was archived by the owner on github Feb 20, 2023 (https://github.com/python-xmp-toolkit/python-xmp-toolkit). I used fstop (on android) to tag images, geeqie sees the Keywords. This solution is revealing them.

Thank you assaf-ge.

Indican answered 14/3, 2023 at 14:32 Comment(2)
PLUS : pip install instruction, MINUS: for incomplete exampleOlympiaolympiad
Sorry, while editing your post, I found that the import line was already in there, but not displayed.Olympiaolympiad

© 2022 - 2024 — McMap. All rights reserved.