How to Embed JSON Metadata into Images Using Python and ExifTool


Managing photos and videos can be overwhelming, especially when you want to preserve metadata like descriptions, locations, and timestamps. Google Takeout provides a way to download your data, including photos and videos, along with their metadata in JSON format. In this post, I'll guide you through a Python script that embeds JSON metadata into image files using ExifTool. We'll also cover how to install Python and ExifTool on your system.

#### Prerequisites

1. **Python**: A popular programming language.
2. **ExifTool**: A platform-independent Perl library plus a command-line application for reading, writing, and editing meta information in a wide variety of files.

### Step 1: Install Python

#### macOS
1. Open Terminal.
2. Install Homebrew if you haven't already:
   ```sh
   /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
   ```
3. Install Python using Homebrew:
   ```sh
   brew install python
   ```

#### Windows
1. Download Python from the [official website](https://www.python.org/downloads/).
2. Run the installer and ensure you check the box that says "Add Python to PATH."
3. Follow the prompts to complete the installation.

#### Linux
Most Linux distributions come with Python pre-installed. You can check by running:
```sh
python3 --version
```
If not installed, you can typically install it using your package manager. For example, on Debian-based systems:
```sh
sudo apt update
sudo apt install python3
```

### Step 2: Install ExifTool

#### macOS
1. Open Terminal.
2. Install ExifTool using Homebrew:
   ```sh
   brew install exiftool
   ```

#### Windows
1. Download ExifTool from the [official website](https://exiftool.org/).
2. Extract the contents and follow the instructions in the README file to set it up.

#### Linux
Most Linux distributions include ExifTool in their package repositories. For example, on Debian-based systems:
```sh
sudo apt update
sudo apt install libimage-exiftool-perl
```

### Step 3: The Python Script

Below is a Python script to embed JSON metadata into image files. This script iterates through a directory, finds JSON files, and embeds their data into the corresponding media files using ExifTool.

```python
import json
import subprocess
import os

# Directory containing the media and JSON files
directory = '/Users/isobelouthwaite/Downloads/Takeout  1/Google Photos/Photos from 2023'

# Check if exiftool is installed
def check_exiftool():
    try:
        result = subprocess.run(['exiftool', '-ver'], capture_output=True, text=True)
        if result.returncode == 0:
            print(f"ExifTool version {result.stdout.strip()} found.")
            return True
        else:
            print("ExifTool is not installed or not found in PATH.")
            return False
    except FileNotFoundError:
        print("ExifTool is not installed or not found in PATH.")
        return False

# Embed JSON metadata into images
def embed_metadata(directory):
    json_files = [filename for filename in os.listdir(directory) if filename.endswith('.json')]
    total_files = len(json_files)
    altered_files = 0
    
    file_types = {'jpeg': 0, 'mpeg4': 0, 'heic': 0, 'others': 0}
    
    print(f"Found {total_files} JSON files to process.")
    
    for count, filename in enumerate(json_files, 1):
        json_filepath = os.path.join(directory, filename)
        media_filepath = os.path.join(directory, filename.replace('.json', ''))
        
        # Determine the file type
        if media_filepath.lower().endswith('.jpeg') or media_filepath.lower().endswith('.jpg'):
            file_types['jpeg'] += 1
        elif media_filepath.lower().endswith('.mp4'):
            file_types['mpeg4'] += 1
        elif media_filepath.lower().endswith('.heic'):
            file_types['heic'] += 1
        else:
            file_types['others'] += 1
        
        # Read JSON data
        with open(json_filepath, 'r') as json_file:
            json_data = json.load(json_file)
        
        # Embed JSON data into image file using ExifTool
        result = subprocess.run(['exiftool', '-json=' + json.dumps(json_data), media_filepath])
        
        # Check if the embedding was successful
        if result.returncode == 0:
            # Remove the JSON file if embedding was successful
            os.remove(json_filepath)
            altered_files += 1
            print(f"[{count}/{total_files}] Embedded metadata and removed {filename}")
        else:
            print(f"[{count}/{total_files}] Failed to embed metadata for {filename}")

    # Print summary
    print("\nSummary:")
    print(f"Total files processed: {total_files}")
    print(f"Files successfully altered: {altered_files}")
    print("File types:")
    for file_type, count in file_types.items():
        print(f"  {file_type.upper()}: {count}")

if __name__ == "__main__":
    if check_exiftool():
        input("ExifTool is installed. Press Enter to start embedding metadata...")
        embed_metadata(directory)
    else:
        print("Please install ExifTool and ensure it is available in your system's PATH.")
        input("Press Enter to exit...")

print("Embedding completed.")
input("Press Enter to exit...")
```

### How It Works

1. **Check if ExifTool is Installed**: The script first checks if ExifTool is installed by running `exiftool -ver`.
2. **Process Files**: It then looks for JSON files in the specified directory and matches them with their corresponding media files.
3. **Embed Metadata**: For each JSON file, the script reads the metadata and embeds it into the media file using ExifTool.
4. **Summary**: After processing all files, the script prints a summary showing the total number of files processed, how many were successfully altered, and the count of each file type.

### Running the Script

1. Ensure Python and ExifTool are installed and accessible in your system's PATH.
2. Save the script to a file, e.g., `embed_metadata.py`.
3. Open a terminal and navigate to the directory where the script is saved.
4. Run the script:
    ```sh
    python3 embed_metadata.py
    ```

This script provides a straightforward way to preserve and manage your photo metadata, ensuring that all your memories are well-documented and organized. Happy scripting!


Date Added: