Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract GPS location from HEIC files?

I use the following code to extract GPS location both from JPG and HEIC files:

#coding=utf-8
from PIL import Image
from urllib.request import urlopen
from PIL.ExifTags import TAGS
from PIL.ExifTags import GPSTAGS

from pillow_heif import register_heif_opener

def get_exif(filename):
    image = Image.open(filename)
    image.verify()
    return image._getexif()

def get_geotagging(exif):
    if not exif:
        raise ValueError("No EXIF metadata found")

    geotagging = {}
    for (idx, tag) in TAGS.items():
        if tag == 'GPSInfo':
            if idx not in exif:
                raise ValueError("No EXIF geotagging found")

            for (key, val) in GPSTAGS.items():
                if key in exif[idx]:
                    geotagging[val] = exif[idx][key]

    return geotagging

register_heif_opener()

my_image='IMG_9610.HEIC'
#my_image='IMG_20210116_215317.jpg'

exif = get_exif(my_image)
labeled = get_geotagging(exif)
print(labeled)

This code works well with JPEG files, but returns the following error with HEIC:

AttributeError: _getexif

If I add the following function

def get_labeled_exif(exif):
    labeled = {}
    for (key, val) in exif.items():
        labeled[TAGS.get(key)] = val

    return labeled

and replace '_getexif()' with 'getexif()' then it works for both files, but the data is encrypted there - 'GPSInfo': 1234 and get_geotagging() doesn't work for such exif.

How could I fix it?

like image 473
LA_ Avatar asked Jan 22 '26 21:01

LA_


1 Answers

UPDATED POST 06-12-2022

The code below is able to extract the GEO tagging information from a HEIC image file on my system.

from PIL import Image
from pillow_heif import register_heif_opener


def get_exif(filename):
    image = Image.open(filename)
    image.verify()
    return image.getexif().get_ifd(0x8825)


def get_geotagging(exif):
    geo_tagging_info = {}
    if not exif:
        raise ValueError("No EXIF metadata found")
    else:
        gps_keys = ['GPSVersionID', 'GPSLatitudeRef', 'GPSLatitude', 'GPSLongitudeRef', 'GPSLongitude',
                    'GPSAltitudeRef', 'GPSAltitude', 'GPSTimeStamp', 'GPSSatellites', 'GPSStatus', 'GPSMeasureMode',
                    'GPSDOP', 'GPSSpeedRef', 'GPSSpeed', 'GPSTrackRef', 'GPSTrack', 'GPSImgDirectionRef',
                    'GPSImgDirection', 'GPSMapDatum', 'GPSDestLatitudeRef', 'GPSDestLatitude', 'GPSDestLongitudeRef',
                    'GPSDestLongitude', 'GPSDestBearingRef', 'GPSDestBearing', 'GPSDestDistanceRef', 'GPSDestDistance',
                    'GPSProcessingMethod', 'GPSAreaInformation', 'GPSDateStamp', 'GPSDifferential']

        for k, v in exif.items():
            try:
                geo_tagging_info[gps_keys[k]] = str(v)
            except IndexError:
                pass
        return geo_tagging_info


register_heif_opener()

my_image = 'IMG_8362.heic'
image_info = get_exif(my_image)
results = get_geotagging(image_info)
print(results)
# x used to mask data
{'GPSLatitudeRef': 'N', 
'GPSLatitude': '(3x.0, 5x.0, 1x.0x)', 
'GPSLongitudeRef': 'W', 
'GPSLongitude': '(8x.0, 2x.0, 5x.2x)', 
'GPSAltitudeRef': "b'\\x00'", 
'GPSAltitude': '279.63243243243244', 
'GPSSpeedRef': 'K', 
'GPSSpeed': '0.04649941997239198', 
'GPSImgDirectionRef': 'T', 
'GPSImgDirection': '274.37165833514456', 
'GPSDestBearingRef': 'T', 
'GPSDestBearing': '27x.37165833514456', 
'GPSDateStamp': '2022:06:12'}
----------------------------------------
My system information
----------------------------------------
Platform:     Apple
OS Version:   macOS Catalina 10.15.7
Python: 3.9
Pillow: 9.1.1
pillow_heif: 0.3.0
----------------------------------------

ORIGINAL POST 06-11-2022

The short answer is that Pillow does not currently support the High Efficiency Image Format (HEIF) file format.

Reference:

  • 2017: Feature Request: Support HEIC
  • 2017: Support for HEIF
  • 2020: HEIF plugin

One of the workarounds for this issue is pyheif. This Python package has the functionality to covert a HEIC image to a JPEG one. After this transformation Pillow will be able to read the data from the image.

Another workaround for this format reading problem is piexif. Here is an answer that I posted on converting a TIFF file to a JPEG one for reading with Pillow.

You could also use ExifTool, which reads HEIC files out of the box. Using it is slightly more complicated, because it requires using subprocess.

like image 96
Life is complex Avatar answered Jan 25 '26 22:01

Life is complex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!