Skip to content

Latest commit

 

History

History
80 lines (66 loc) · 3.1 KB

File metadata and controls

80 lines (66 loc) · 3.1 KB

Photo Tagger

A Python script that automatically tags photos with metadata including keywords, headlines, and abstracts using AI-powered image analysis. The metadata is written back to the image, so that every capable photo library application (e.g. Immich) can read this.

Features

  • Automatic generation of keywords/tags based on image content. This version creates English and German keywords. Feel free to modify to your needs
  • Generation of headlines and abstracts for images
  • Support for IPTC and XMP metadata standards
  • Recursive batch processing of multiple (JPG, HEIC) images in a directory
  • Integration with OpenAI API for image analysis
  • Docker containerization for easy deployment

Result in Immich

Description tags

Performance

I run this locally using Ollama and Open WebUI with Gemma3 27b on an Apple M4 Max. Per photo it takes around 20-25sec. With more capabale hardware (Nvidia 4090, 5090, currenty impossible to get anything with a reasonable pricing) or a cloud service this is probably dramatatically faster.

Requirements

  • Python 3.12+
  • ExifTool
  • A key to any OpenAI compatible Server, e.g. OpenAI or Ollama with or without using Open WebUI

Installation

Using Docker (Recommended)

Pull and run the image. The Logfile will be created in the current directory:

docker run -v ./:/var/log \
    -v YOUR_PHOTO_DIR:/app/images \
    hulk66/photo-tagging python tagger.py \
    --ai_server YOUR_AI_SERVER \
    --api_key YOUR_API__KEY \
    --model YOUR_MODEL /app/images

Direct Installation

  1. Make sure ExifTool is installed on your system
  2. Recommended: create a virtual environment (I use Conda)
  3. Install the Python dependencies
pip install -r requirements.txt

Usage

The script can be run directly or through Docker as seen above. Under the hood it uses ExifTool to read and write IPTC and XMP data. While writing back, ExifTool creates a copy of the original file (name.jpg_original) as a safty measure. Can be probably disabled but I find it useful.

Command Line Arguments

directory: Path to the directory containing photos (required)
--model: AI model to use (default: "gemma3:27b")
--overwrite: Overwrite existing metadata if it exists (default: False)
--ai_server: URL of the OpenAI API server
--api_key: Your OpenAI API key
--log_file: Path where log files should be stored

Example

python tagger.py /path/to/photos \
    --model "gemma3:27b" \
    --overwrite \
    --ai_server "https://api.openai.com/v1" \
    --api_key "your-api-key" \
    --log_file "/var/log/photo_tagger.log"

Docker Configuration

The provided Dockerfile creates a container with:

  • Python 3.12-slim as the base image
  • ExifTool installed for metadata manipulation
  • Required Python packages installed from requirements.txt

Logging

Logs are written to the specified log file (default: /var/log/photo_tagger.log)

License

(c) Tobias Himstedt, 2025

GPL