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_value eerst: 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.

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: XmpPacketWrapper en XmpDublinCorePackage worden 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: set vervangt dc:subject, dus additieve tagging betekent eerst lezen, uitbreiden, schrijven.
  • Schrijf identiteit naar beide schema’s: het combineren van dc:creator met xmp:CreatorTool houdt 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:

Aanvullende bronnen

Vragen over je XMP‑workflow? Vraag het op het support forum.