↓ Skip to Main Content

Metadata Stripping Utility (Python)

·· loading · loading · ·
Table of Contents
AI Workflow Notice: This Python script was created using AI tools to solve a problem. I gave the AI the specific language to use, the functions to perform, the tool it should import, file types to support, and type of logging to output. Additionally, I verified that the script works as intended and that the metadata is stripped as expected. Additional revisions were made to ensure the intended functionality was exact.

This is a Python script that uses Pillow’s built-in utility to create cleaned copies of photos while preserving the original filenames. It reads images from an input folder, removes common embedded metadata, and saves the cleaned versions to an output folder.

This is useful before publishing photos to a website or static site generator, such as Hugo (which what this website uses). Static sites often serve image files exactly as provided, which means metadata, such as GPS location, camera details, timestamps, software tags, and descriptions may remain embedded unless first removed.

Python Code
#

from pathlib import Path
from PIL import Image

# Use the folder where this script is located
script_folder = Path(__file__).resolve().parent

# Source/output folders beside the script
input_folder = script_folder / "input"
output_folder = script_folder / "output"

supported_extensions = {".jpg", ".jpeg", ".png", ".webp"}

output_folder.mkdir(parents=True, exist_ok=True)

cleaned_count = 0
skipped_count = 0
failed_count = 0

if not input_folder.exists():
    print(f"Input folder does not exist: {input_folder}")
    raise SystemExit(1)

for file in sorted(input_folder.iterdir(), key=lambda f: f.name.lower()):
    if not file.is_file():
        continue

    if file.suffix.lower() not in supported_extensions:
        skipped_count += 1
        print(f"Skipped unsupported file: {file.name}")
        continue

    output_file = output_folder / file.name

    try:
        with Image.open(file) as img:
            # Rebuild image from pixel data without carrying metadata forward.
            cleaned = Image.new(img.mode, img.size)
            cleaned.putdata(img.get_flattened_data())

            extension = file.suffix.lower()

            if extension in {".jpg", ".jpeg"}:
                # JPEG does not support transparency.
                if cleaned.mode in ("RGBA", "LA", "P"):
                    cleaned = cleaned.convert("RGB")

                cleaned.save(output_file, quality=95, optimize=True)

            elif extension == ".png":
                cleaned.save(output_file, optimize=True)

            elif extension == ".webp":
                cleaned.save(output_file, quality=95, method=6)

            cleaned_count += 1
            print(f"Cleaned: {file.name}")

    except Exception as error:
        failed_count += 1
        print(f"Failed: {file.name} -> {error}")

print()
print("Finished.")
print(f"Cleaned: {cleaned_count}")
print(f"Skipped: {skipped_count}")
print(f"Failed:  {failed_count}")
print(f"Output:  {output_folder}")

Usage
#

  1. Place strip.py in a folder.

  2. Create two folders beside it:

C:\path\where\strip\script\lives\input\
C:\path\where\strip\script\lives\output\
  1. Place photos in the input folder.

  2. Run the following command:

python .\strip.py
  1. Use the cleaned photos from the output folder and remove the originals. Re-use the input and output folders for future projects.
Reply by Email