Skip to content

Instantly share code, notes, and snippets.

@koloved
Last active June 3, 2025 11:17
Show Gist options
  • Select an option

  • Save koloved/449c14955f9bc6a88d5a84e6b01cf688 to your computer and use it in GitHub Desktop.

Select an option

Save koloved/449c14955f9bc6a88d5a84e6b01cf688 to your computer and use it in GitHub Desktop.
txt tag files to XMP files converter
# This Python script is a tag conversion utility that transforms text-based tag files into XMP (Extensible Metadata Platform)
# sidecar files for image management, specifically formatted for digiKam photo management software.
# txt tag sample - 1girl looking_at_viewer split yoga_pose
import os
import glob
# Function to convert tags string to XMP format
def tags_to_xmp(tags_string):
# Normalize tags string by replacing commas with spaces and splitting
tags = [tag.strip() for tag in tags_string.replace(',', ' ').split() if tag.strip()]
# Build XMP XML structure
xmp_template = '''<?xml version="1.0" encoding="UTF-8"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="" xmlns:digiKam="http://www.digikam.org/ns/1.0/">
<digiKam:TagsList>
<rdf:Seq>
{tags_xml}
</rdf:Seq>
</digiKam:TagsList>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>'''
tags_xml = '\n'.join([f' <rdf:li>{tag}</rdf:li>' for tag in tags])
return xmp_template.format(tags_xml=tags_xml)
# Supported image extensions
image_extensions = ['.jpg', '.jpeg', '.png', '.jxl', '.webp']
# Counters
image_count = 0
txt_count = 0
xmp_created_count = 0
missing_txt_files = []
# Walk through current directory and subdirectories
for root, dirs, files in os.walk('.'):
for file in files:
file_lower = file.lower()
if any(file_lower.endswith(ext) for ext in image_extensions):
image_count += 1
base_name = os.path.splitext(file)[0]
txt_path = os.path.join(root, base_name + '.txt')
image_path = os.path.join(root, file)
xmp_path = image_path + '.xmp'
if os.path.exists(txt_path):
txt_count += 1
with open(txt_path, 'r') as txt_file:
tags = txt_file.read().strip()
xmp_content = tags_to_xmp(tags)
with open(xmp_path, 'w') as xmp_file:
xmp_file.write(xmp_content)
xmp_created_count += 1
print(f"Created XMP for {image_path}")
else:
missing_txt_files.append(image_path)
# Summary log
print(f"\nSummary:")
print(f"Found {image_count} images, {txt_count} txt files, and created {xmp_created_count} xmp files.")
if missing_txt_files:
print(f"{len(missing_txt_files)} image files do not have corresponding txt tags files:")
for missing in missing_txt_files[:10]: # Show first 10 to avoid excessive output
print(f" - {missing}")
if len(missing_txt_files) > 10:
print(f" ... and {len(missing_txt_files) - 10} more")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment