Extracting Image Metadata Using Python: A Step-by-Step Guide with metaX
In this guide, I'll walk you through how to create a simple Python tool, I call metaX, that extracts metadata from images, including EXIF data like camera information. date taken and GPS coordinates.
Why Python for Metadata Extraction?
Python is an extremely versatile language, and its ease of use makes it perfect for all kinds of tasks. Whether you're building web apps, writing automation scripts, or developing hacking tools (in an ethical hacking context, of course!), Python has your back. With a large number of libraries and proof-of-concepts out there, it's a breeze to get started.
In this tutorial, we'll use Python to:
- Extract basic image metadata.
- Retrieve EXIF metadata from images.
- Convert GPS coordinates from EXIF data into human-readable decimal format.
If you'd like to download the script or contribute to its development, check out the GitHub repository https://github.com/Dan-Duran/metaX.git.
Let's get started!
Step 1: Set Up Your Project
Create a New Directory
First, fire up your terminal and create a new directory for this project:
mkdir metaX
cd metaX
mkdir app
Create a Virtual Environment
We'll need to set up a Python virtual environment to isolate this project's dependencies. In your terminal, type:
python3 -m venv .venv
This will create a virtual environment named .venv
.
Activate the Virtual Environment
To activate the virtual environment, run the following command based on your operating system:
- On macOS/Linux:
source .venv/bin/activate
- On Windows:
source .venv/Scripts/activate
You should now see the virtual environment name appear in your terminal prompt, indicating that it's active.
Install Required Python Libraries
We'll be using two Python libraries: Pillow (for image handling) and Exifread (for extracting EXIF metadata). Install them using pip:
pip install pillow exifread
Make sure your pip
is up-to-date:
pip install --upgrade pip
Now that we have our environment ready, let's move on to coding!
Step 2: Write the Python Script
Create the metaX.py
Script
Inside the app
directory, create a new Python script:
cd app
touch metaX.py
Now open the metaX.py
file in your favorite editor (e.g., VSCode). Here's the basic structure we'll follow.
Import the Required Libraries
We need Pillow and Exifread to handle image files and extract metadata. Add these import statements at the top of your script:
from PIL import Image
import exifread
Convert GPS Coordinates to Decimal
We'll write a function to convert the GPS coordinates from degrees, minutes, and seconds format (used in EXIF data) to decimal degrees:
def convert_to_degrees(value):
d = float(value.values[0])
m = float(value.values[1])
s = float(value.values[2])
return d + (m / 60.0) + (s / 3600.0)
This function converts the GPS data into a format that can be easily copied into Google Maps.
Extract Basic Metadata
Next, we'll write a function to extract basic metadata (like format, size, and mode) from an image:
def get_basic_metadata(image_path):
with Image.open(image_path) as img:
print(f"\n[Basic Image Information]")
print(f"Image Format: {img.format}")
print(f"Image Size: {img.size} pixels")
print(f"Image Mode: {img.mode}\n")
Extract EXIF Metadata
Now, let's create the function to extract EXIF metadata from the image:
def get_exif_metadata(image_path):
with open(image_path, 'rb') as img_file:
tags = exifread.process_file(img_file)
print("[EXIF Metadata]")
exif_keys = [
"Image Make", "Image Model", "Image DateTime",
"EXIF FNumber", "EXIF ExposureTime", "EXIF ISOSpeedRatings",
"EXIF FocalLength", "EXIF LensModel"
]
for tag in exif_keys:
if tag in tags:
print(f"{tag}: {tags[tag]}")
# Extract GPS info if available
print("\n[GPS Information]")
gps_latitude = tags.get("GPS GPSLatitude")
gps_latitude_ref = tags.get("GPS GPSLatitudeRef")
gps_longitude = tags.get("GPS GPSLongitude")
gps_longitude_ref = tags.get("GPS GPSLongitudeRef")
if gps_latitude and gps_latitude_ref and gps_longitude and gps_longitude_ref:
lat = convert_to_degrees(gps_latitude)
lon = convert_to_degrees(gps_longitude)
if gps_latitude_ref.values[0] != 'N':
lat = -lat
if gps_longitude_ref.values[0] != 'E':
lon = -lon
print(f"Latitude: {lat:.6f}°")
print(f"Longitude: {lon:.6f}°")
else:
print("No GPS data available.")
This function extracts the camera details and attempts to extract GPS data, if available, and converts it to a human-readable format.
Main Script Logic
Finally, let's write the main logic that will prompt the user for an image file and call our metadata functions:
if __name__ == "__main__":
image_path = input("Enter the path to the image: ")
try:
print("[+] Extracting basic metadata...")
get_basic_metadata(image_path)
print("\n[+] Extracting EXIF metadata...")
get_exif_metadata(image_path)
except FileNotFoundError:
print("[-] Error: The specified file was not found.")
Step 3: Run the Script
You're now ready to run the script and see it in action! In your terminal, run:
python metaX.py
It will prompt you to enter the path to an image file. For example, you could use an image file like doggies.jpg
in the same directory.
Enter the path to the image: doggies.jpg
Example Output
You'll see basic image metadata, camera details, and, if available, the GPS location in decimal degrees:
[+] Extracting basic metadata...
[Basic Image Information]
Image Format: JPEG
Image Size: (4032, 3024) pixels
Image Mode: RGB
[+] Extracting EXIF metadata...
[EXIF Metadata]
Image Make: iPhone
Image Model: iPhone 15 Pro Max
Image DateTime: 2024:09:25 10:45:00
EXIF FNumber: F/1.8
EXIF ExposureTime: 1/60 sec
EXIF ISOSpeedRatings: 100
EXIF FocalLength: 4.2 mm
EXIF LensModel: iPhone 15 Pro Max back dual camera
[GPS Information]
Latitude: 3.645678°
Longitude: -9.380123°
And that's it! You've successfully built a Python tool to extract metadata from images. This tool is incredibly useful for forensic analysis and ethical hacking tasks like OSINT (Open Source Intelligence).
Don't forget to subscribe to our channel and join the conversation on our Discord server. Stay tuned for more tutorials, and see you next time!
Latest Comments
Sign in to add a commentNo comments yet. Be the first to comment!