Volledig werkend voorbeeld beschikbaar op GitHub:
manage-xmp-in-psd-and-ai-files-python
Inleiding
Een marketingteam zet 400 PSD‑bestanden in je asset‑platform. Het uploaden werkt. Zoeken niet, omdat geen van de bestanden trefwoorden bevat, de helft geen copyright‑vermelding heeft, en de namen van de ontwerpers alleen in een spreadsheet ergens staan. De oplossing is geen grotere spreadsheet. XMP‑beheer is een GroupDocs.Metadata‑functionaliteit voor Python via .NET die het metadata‑pakket dat in Photoshop‑PSD‑ en Illustrator‑AI‑bestanden is ingebed, kan lezen en schrijven, waardoor eigendom‑ en zoekgegevens in de bestanden zelf kunnen worden opgeslagen.
XMP is een XML‑pakket binnen een binair container, georganiseerd in schema’s: Dublin Core voor de velden die elk systeem begrijpt, het Photoshop‑schema voor redactionele context, XmpBasic voor tool‑identiteit. Een PSD handmatig parseren om dat pakket te bereiken is echt moeilijk. Met de Metadata‑klasse is het drie attribuut‑opzoekingen, en dezelfde code werkt voor AI‑bestanden.
Deze tutorial doorloopt de volledige round‑trip in vier stappen: maak een momentopname van het hele pakket, lees de relevante schema’s, schrijf copyright en maker, en tag trefwoorden voor zoeken. Elk fragment komt uit een uitvoerbare repository die controleert dat de geschreven waarden behouden blijven.
Vereisten
Zorg ervoor dat je het volgende hebt voordat je begint:
- Python 3 met pip
- GroupDocs.Metadata voor Python via .NET (de repository pinnt versie 26.5)
- Een PSD‑ of AI‑bestand om mee te experimenteren
Installatie
pip install groupdocs-metadata-net==26.5
Stap 1 - Momentopname van het volledige XMP‑pakket
Begin met alles te bekijken wat het bestand bevat. De momentopname doorloopt het root‑pakket, elk geregistreerd schema, en ten slotte veegt de eigenschap‑boom af voor alles wat niet‑standaard is, en verzamelt alles in één platte dict.
result = {}
def put(props, prop):
value = (str(prop.interpreted_value) if prop.interpreted_value is not None
else (str(prop.value) if prop.value is not None else ""))
props[prop.name] = value
with Metadata("campaign-hero.psd") as metadata:
root = metadata.get_root_package()
xmp = getattr(root, "xmp_package", None)
if xmp is not None:
for p in xmp: # root‑pakket‑eigenschappen
put(result, p)
schemes = xmp.schemes
for scheme in (schemes.dublin_core, schemes.xmp_basic, schemes.photoshop,
schemes.camera_raw, schemes.paged_text,
schemes.xmp_dynamic_media, schemes.xmp_media_management):
if scheme is None:
continue
for p in scheme:
put(result, p)
for p in metadata.find_properties(lambda p: p.name is not None):
if p.name not in result: # vang aangepaste pakketten op
put(result, p)
Belangrijke punten:
interpreted_valueeerst: datums en enumeraties komen mens‑leesbaar in plaats van rauw.- Zeven schema’s plus een sweep: de afsluitende
find_properties‑pass vangt vendor‑pakketten die de benoemde schema’s missen. - Één bestand geopend: de hele momentopname kost één enkele
Metadata‑context, wat belangrijk is bij bulk‑inname.
Tip: indexeer deze dict tijdens de inname en de meeste latere metadata‑vragen worden dan dictionary‑opzoekingen in plaats van bestands‑reads.
Welk XMP‑schema moet mijn integratie eerst lezen?
Begin met Dublin Core. De negen dc‑velden bevatten titel, maker, rechten en onderwerp‑waarden die de meeste DAM‑systemen, zoek‑indexen en licentie‑controles overeenkomen, en zowel PSD‑ als AI‑bestanden exposeren ze identiek. Lees daarna het Photoshop‑schema voor redactionele context zoals City, Credit en DateCreated. Bewaar de volledige‑pakket‑sweep voor inname‑taken die alles moeten vastleggen.
Stap 2 - Lees de schema’s die echte vragen beantwoorden
Voor code die op aanvraag draait, beperk de lezing tot één schema. Dublin Core beantwoordt eigendom‑ en zoekvragen:
dc_fields = {}
with Metadata("campaign-hero.psd") as metadata:
xmp = getattr(metadata.get_root_package(), "xmp_package", None)
dc = xmp.schemes.dublin_core if xmp is not None else None
if dc is not None:
for p in dc:
dc_fields[p.name] = (str(p.interpreted_value)
if p.interpreted_value is not None else
str(p.value) if p.value is not None else "")
print(dc_fields.get("dc:rights", "<no rights recorded>"))
Het Photoshop‑schema werkt op dezelfde manier via getypeerde eigenschappen: ps.color_mode, ps.icc_profile, ps.city, ps.country, ps.date_created, ps.caption_writer, ps.credit en ps.source, elk gelezen met een None‑guard. Dat zijn de velden waarop Bridge, Lightroom en DAM‑zoekfilters voor Adobe‑bestanden filteren.
Let op wat er gebeurt bij bestanden zonder XMP: de guards leveren een lege dict op, geen uitzondering. Vers nieuw geëxporteerde assets maken dit geval routine, dus behoud dat gedrag in je integratie.
Dezelfde drie opzoekingen werken op Illustrator‑bestanden. Vervang campaign-hero.psd door brand-mark.ai en er verandert niets, wat een enkele code‑pad realistisch maakt voor gemengde Adobe‑archieven. In de praktijk bevat een verse AI‑export meestal minder gevulde schema’s dan een Photoshop‑save, dus het lege‑dict‑pad wordt daar vaker getraind.
Stap 3 - Schrijf copyright en maker
Nu het schrijfgedeelte. Eigendom‑stempeling raakt drie velden zodat elke lezer dezelfde identiteit ziet: dc:rights voor de juridische vermelding, dc:creator als een geordende lijst, en xmp:CreatorTool voor tools die het XmpBasic‑schema lezen in plaats van Dublin Core. Ik verloor ooit een middag aan een licentie‑banner die “Unknown author” toonde op assets waarvan de ontwerpers zeker wisten dat ze getagd waren; de waarden zaten in dc:creator terwijl de tool alleen xmp:CreatorTool las. Beide schrijven loste dat type bug op.
with Metadata("campaign-hero.psd") as metadata:
root = metadata.get_root_package()
xmp = getattr(root, "xmp_package", None)
if xmp is None: # bestand heeft helemaal geen XMP
root.xmp_package = XmpPacketWrapper()
xmp = root.xmp_package
if xmp.schemes.dublin_core is None:
xmp.schemes.dublin_core = XmpDublinCorePackage()
dc = xmp.schemes.dublin_core
dc.set_rights("(C) 2026 GroupDocs Sample")
dc.set("dc:creator", XmpArray.from_(["Digital Asset Team"],
XmpArrayType.ORDERED))
if xmp.schemes.xmp_basic is None:
xmp.schemes.xmp_basic = XmpBasicPackage()
xmp.schemes.xmp_basic.creator_tool = "Digital Asset Team"
metadata.save("campaign-hero-stamped.psd")
Belangrijke punten:
- Guards maken ontbrekende lagen:
XmpPacketWrapperenXmpDublinCorePackageworden on demand aangemaakt, zodat het schrijven werkt op bestanden zonder XMP. - GEORDENDE array voor makers: de volgorde van auteurs draagt betekenis, dus de maker‑lijst gebruikt een geordende
XmpArray. - Opslaan naar een nieuw pad: het bronbestand blijft onaangeroerd, wat de juiste standaard is voor export‑stappen.
Stap 4 - Tag trefwoorden voor zoeken
dc:subject is de trefwoord‑zak voor DAM‑zoekindexen. Het schrijven vervangt de hele zak in één oproep:
with Metadata("campaign-hero.psd") as metadata:
root = metadata.get_root_package()
xmp = getattr(root, "xmp_package", None)
if xmp is None:
root.xmp_package = XmpPacketWrapper()
xmp = root.xmp_package
if xmp.schemes.dublin_core is None:
xmp.schemes.dublin_core = XmpDublinCorePackage()
xmp.schemes.dublin_core.set(
"dc:subject",
XmpArray.from_(["landscape", "sunset", "commercial"],
XmpArrayType.UNORDERED))
metadata.save("campaign-hero-tagged.psd")
Trefwoorden gebruiken een UNORDERED‑array omdat de volgorde niets betekent voor een indexeerder. En aangezien set de bestaande zak vervangt, lees eerst de huidige trefwoorden en voeg ze in Python samen wanneer je additieve tagging wilt in plaats van vervanging.
Om elke schrijf‑actie te verifiëren, voer stap 2 opnieuw uit op het output‑bestand. De repository automatiseert precies dat: hij leest zijn outputs opnieuw en controleert dat de copyright‑string en het eerste trefwoord behouden blijven in de opgeslagen bytes.
Praktische toepassingen
DAM‑inname
Voer stap 1 uit op elk binnenkomend bestand en sla de dict op naast het asset‑record. Zoeken, deduplicatie en rechten‑controles draaien dan tegen je database in plaats van het binair‑bestand opnieuw te openen. De momentopname van de kleine voorbeeld‑PSD in de repository levert al een gezonde stapel eigenschappen op in één pass, en dezelfde oproep behoudt zijn vorm wanneer de invoer een map met duizenden bestanden wordt.
Licentie‑handhaving
Voordat een asset naar een klantportaal wordt gestuurd, eis een niet‑lege dc:rights. Bestanden die falen krijgen automatisch stap 3 toegepast, zodat niets zonder vermelding vertrekt.
Batch‑her‑tagging
Wanneer de taxonomie verandert, lees elk bestand’s dc:subject, map oude termen naar nieuwe in Python, en schrijf de samengevoegde zak terug met stap 4. Zowel PSD‑ als AI‑archieven doorlopen dezelfde lus. Geen Photoshop‑licentie vereist.
Best practices en tips
- Beschouw leeg als normaal: bestanden zonder XMP zijn routine, geen fouten; het early‑return‑patroon houdt pipelines soepel.
- Merge vóór het schrijven van trefwoorden:
setvervangtdc:subject, dus additieve tagging betekent eerst lezen, uitbreiden, schrijven. - Schrijf identiteit naar beide schema’s: het combineren van
dc:creatormetxmp:CreatorToolhoudt Dublin Core‑lezers en XmpBasic‑lezers in overeenstemming. - Verifieer writes met een read‑back: een her‑lezen na opslaan is goedkoop en vangt container‑verrassingen direct.
- Licentie voor productie: evaluatiemodus draait alles wat hier getoond wordt; gebruik een licentie vóór je echte klant‑assets stempelt.
Conclusie
Het lezen en schrijven van XMP in Adobe‑bestanden reduceert zich tot drie handelingen: los het pakket op via get_root_package(), bescherm het schema dat je nodig hebt, en lees of schrijf getypeerde waarden. Met die handelingen heb je in deze tutorial een volledige round‑trip gebouwd, van pakket‑momentopname tot schema‑lezingen, copyright‑stempeling en trefwoord‑tagging, met dezelfde code voor PSD‑ en AI‑bestanden.
Klaar om dit in je project te implementeren? Hier zijn enkele vervolgstappen:
- Lees de documentatie Working with XMP metadata voor het bijwerken en verwijderen van pakketten
- Volg de integration‑focused use case guide die op dezelfde repository is gebaseerd
- Clone het sample project en voer het uit tegen je eigen assets
Aanvullende bronnen
- GroupDocs.Metadata Documentation
- API Reference
- Sample Projects on GitHub
- GroupDocs.Metadata Blog Category
Vragen over je XMP‑workflow? Vraag het op het support forum.