A Python tool to export face recognition data from Immich photo management system to DigiKam-compatible XMP format files.
ppocrv5-rknn/: unified one-click pipeline for PP-OCRv5 mobile/server det/rec model export and RKNN conversion.ml-models-textual-rknn/: utilities for validatingml-modelstextual ONNX/RKNN exports on RK3576 hardware.immich-rk3576-tools/: RK3576 machine-learning deployment helpers migrated fromimmichrepo (prepare/run, bundle export, Docker deploy docs/scripts). Quick start:immich-rk3576-tools/README.md
- π Face Recognition Data Export - Retrieve complete face recognition data from Immich API
- π·οΈ Immich Tag Backup - Preserve ordinary Immich asset tags and write them to Immich-readable XMP
- π§Ύ Metadata Backup - Preserve asset EXIF/location/rating metadata in the JSON export and companion XMP
- π Directory Structure Preservation - Output files maintain original photo directory structure
- π― DigiKam Compatible - Generate standard XMP sidecar files, fully compatible with DigiKam
- βοΈ Flexible Configuration - Support JSON configuration files and environment variables
- π Security First - Prefer Immich API key authentication; sensitive configurations are automatically git-ignored
- π Detailed Statistics - Generate comprehensive export statistics reports
- π Efficient Processing - Smart batch processing, supports large photo libraries
- π Two-Stage Processing - Export to JSON first, then generate XMP files (flexible workflow)
- π― Debug-Friendly - Support limiting processed assets quantity for testing
git clone https://github.com/yuhuan417/immich-scripts.git
cd immich-scriptspip install requests# Copy template file
cp config.json.template config.json
# Edit configuration file
nano config.jsonFill in your Immich server information in config.json:
{
"immich": {
"base_url": "https://your-immich-server.com",
"api_key": "your-api-key",
"email": "",
"password": ""
},
"settings": {
"request_timeout": 30,
"retry_attempts": 3,
"retry_backoff_seconds": 1
},
"output": {
"digikam_xmp_dir": "digikam_xmp_sidecars",
"json_export_dir": "json_exports"
},
"xmp": {
"sidecar_naming": "extension-xmp",
"include_unnamed_faces": false,
"unnamed_face_name": "Unnamed Face",
"write_dc_subject": true,
"write_asset_tags": true,
"write_asset_tags_to_dc_subject": true,
"write_asset_metadata": true,
"write_digikam_tags": false,
"write_lightroom_hierarchical_subject": false,
"people_tag_prefix": "People"
},
"search": {
"asset_type": "IMAGE",
"visibility": "timeline",
"with_people": true
}
}export IMMICH_BASE_URL="https://your-immich-server.com"
export IMMICH_API_KEY="your-api-key"IMMICH_API_KEY is the recommended authentication method. IMMICH_EMAIL and IMMICH_PASSWORD are still supported as a fallback for older setups.
# Run complete workflow (export to JSON then generate XMP)
python export_face.py# Run only Stage 1: Export to JSON file
python export_face.py --stage1-only
# Run only Stage 2: Generate XMP from existing JSON file
python export_face.py --stage2-only --json-file path/to/export.json
# Limit processed assets for testing (e.g., process only 50 assets)
python export_face.py --max-assets 50
# Specify custom output directories
python export_face.py --json-dir my_json_exports --xmp-dir my_xmp_files
# Write sidecars beside the original files so Immich can detect them directly
python export_face.py --stage2-only --json-file path/to/export.json --write-next-to-original
# Include unnamed faces with a placeholder name (disabled by default)
python export_face.py --include-unnamed-faces
# Generate XMP without ordinary Immich tags or EXIF/location metadata
python export_face.py --stage2-only --json-file path/to/export.json --no-asset-tags --no-asset-metadata
# Combine multiple options
python export_face.py --stage1-only --max-assets 100 --json-dir test_outputFor the export design and compatibility plan, please refer to DESIGN.md, which includes:
- π§ Immich API compatibility notes
- π οΈ DigiKam/MWG XMP design
- π XML safety requirements
- π‘οΈ Export validation plan
- π Implementation migration steps
After running the script, the following will be generated in the configured output directories:
json_exports/
βββ immich_faces_export_20251013_143022.json # Face, tag, person, and metadata backup
βββ ...
The current export schema is schema_version: 3. Each exported asset contains normalized face boxes, ordinary Immich asset tags, selected asset metadata under asset_metadata.exif_info, and a top-level people index preserves person-level Immich fields such as hidden/favorite state when the API returns them. Assets are exported when they have faces or ordinary tags.
digikam_xmp_sidecars/
βββ export_summary.json # Export statistics report
βββ your-photo1.jpg.xmp # XMP sidecar file
βββ your-photo2.jpg.xmp
βββ subdirectory/
βββ photo3.jpg.xmp
βββ photo4.jpg.xmp
Immich detects sidecars at originalPath + ".xmp" first, for example IMG_0001.jpg.xmp, then falls back to IMG_0001.xmp. The default extension-xmp naming is chosen to match that preferred Immich and DigiKam sidecar form. Use --write-next-to-original only when the machine running the script can safely write to the original photo library path.
Ordinary Immich asset tags are written to digiKam:TagsList by default because Immich reads that field from XMP sidecars. They are also mirrored into dc:subject by default for broader keyword search compatibility. Person names remain in MWG face regions and dc:subject; use --write-digikam-tags only if you also want person names added to digiKam:TagsList with the configured people_tag_prefix.
- πΈ Photo Management Migration - Maintain face recognition data when migrating from Immich to DigiKam
- π Metadata Backup - Backup face recognition information in standard XMP format
- π₯ People Tag Management - Sync people tags between different photo management software
- π Data Analysis - Analyze person appearance frequency and distribution in photo libraries
- π Workflow Flexibility - Two-stage processing allows data export and XMP generation to be performed separately
- π§ͺ Development & Testing - Limit processed assets for debugging and development purposes
| Configuration Item | Environment Variable | Default Value | Description |
|---|---|---|---|
immich.base_url |
IMMICH_BASE_URL |
- | Immich server address |
immich.api_key |
IMMICH_API_KEY |
- | Immich API key (recommended) |
immich.email |
IMMICH_EMAIL |
- | Login email (fallback only) |
immich.password |
IMMICH_PASSWORD |
- | Login password (fallback only) |
settings.request_timeout |
IMMICH_REQUEST_TIMEOUT |
30 | API request timeout (seconds) |
settings.retry_attempts |
IMMICH_RETRY_ATTEMPTS |
3 | Number of retry attempts |
settings.retry_backoff_seconds |
IMMICH_RETRY_BACKOFF_SECONDS |
1 | Base retry backoff in seconds |
output.digikam_xmp_dir |
OUTPUT_DIGIKAM_XMP_DIR |
digikam_xmp_sidecars | XMP output directory |
output.json_export_dir |
OUTPUT_JSON_EXPORT_DIR |
json_exports | JSON export directory |
xmp.sidecar_naming |
XMP_SIDECAR_NAMING |
extension-xmp | extension-xmp or replace-extension |
xmp.include_unnamed_faces |
XMP_INCLUDE_UNNAMED_FACES |
false | Export unnamed faces with a placeholder |
xmp.write_dc_subject |
XMP_WRITE_DC_SUBJECT |
true | Write person names as XMP subjects |
xmp.write_asset_tags |
XMP_WRITE_ASSET_TAGS |
true | Write ordinary Immich asset tags to digiKam:TagsList |
xmp.write_asset_tags_to_dc_subject |
XMP_WRITE_ASSET_TAGS_TO_DC_SUBJECT |
true | Mirror ordinary Immich tags into dc:subject |
xmp.write_asset_metadata |
XMP_WRITE_ASSET_METADATA |
true | Write exported EXIF/location/rating metadata fields into XMP |
xmp.write_digikam_tags |
XMP_WRITE_DIGIKAM_TAGS |
false | Also write person names as digiKam:TagsList people tags |
xmp.write_lightroom_hierarchical_subject |
XMP_WRITE_LIGHTROOM_HIERARCHICAL_SUBJECT |
false | Write lr:hierarchicalSubject people tags |
xmp.people_tag_prefix |
XMP_PEOPLE_TAG_PREFIX |
People | Prefix used for optional hierarchical people tags |
search.asset_type |
IMMICH_SEARCH_ASSET_TYPE |
IMAGE | Asset type sent to Immich metadata search |
search.visibility |
IMMICH_SEARCH_VISIBILITY |
timeline | Asset visibility sent to Immich metadata search |
# Syntax check
python3 -m py_compile export_face.py
# Import test
python3 -c "from export_face import ConfigLoader; print('OK')"
# Unit tests
python3 -m unittest# Test environment variable configuration
export IMMICH_API_KEY="test-api-key"
python3 -c "from export_face import ConfigLoader; config = ConfigLoader(); print('Config OK')"A: Check if the server address and API key are correct, and ensure the server is accessible. If you use the legacy fallback flow, also verify email and password.
A: Confirm that your photos have face metadata in Immich and at least one named person. Unnamed faces are skipped by default because Immich ignores unnamed sidecar regions during face import.
A: Ensure the script has permission to create and write to the configured output directory.
A: The script automatically paginates processing and supports large photo libraries. Processing progress will be displayed in real-time. For testing, you can use --max-assets parameter to limit the number of processed assets.
A: Two-stage processing allows you to:
- First export all face recognition data to a JSON file (
--stage1-only) - Then generate XMP files from that JSON data (
--stage2-only)
This provides flexibility for workflows and allows you to review the exported data before generating XMP files.
A: Use the --max-assets parameter to limit the number of assets processed, for example: python export_face.py --max-assets 50 will only process 50 assets.
MIT License - See LICENSE file for details
Issues and Pull Requests are welcome!
For questions or suggestions, please create an issue on GitHub.
β If this project is helpful to you, please give it a Star!