Pełny działający przykład dostępny na GitHubie:
manage-xmp-in-psd-and-ai-files-python
Wprowadzenie
Zespół marketingowy wrzuca 400 plików PSD do Twojej platformy zasobów. Przesyłanie działa. Wyszukiwanie nie, ponieważ żaden z plików nie zawiera słów kluczowych, połowa nie ma informacji o prawach autorskich, a nazwiska projektantów istnieją tylko w jakimś arkuszu kalkulacyjnym. Rozwiązaniem nie jest większy arkusz. Zarządzanie XMP to funkcja GroupDocs.Metadata dla Pythona przez .NET, która odczytuje i zapisuje pakiet metadanych osadzony w plikach Photoshop PSD i Illustrator AI, co oznacza, że informacje o własności i wyszukiwaniu mogą znajdować się w samych plikach.
XMP to pakiet XML wewnątrz kontenera binarnego, podzielony na schematy: Dublin Core dla pól rozumianych przez wszystkie systemy, schemat Photoshop dla kontekstu redakcyjnego, XmpBasic dla tożsamości narzędzia. Ręczne parsowanie PSD, aby dotrzeć do tego pakietu, jest naprawdę trudne. Z klasą Metadata to trzy odwołania do atrybutów, a ten sam kod działa również dla plików AI.
Ten samouczek prowadzi przez pełny cykl w czterech krokach: zrzut całego pakietu, odczyt istotnych schematów, zapis praw autorskich i twórcy oraz oznaczenie słów kluczowych do wyszukiwania. Każdy fragment kodu pochodzi z działającego repozytorium, które sprawdza, że zapisane wartości pozostają w pliku.
Wymagania wstępne
Przed rozpoczęciem upewnij się, że masz:
- Python 3 z pip
- GroupDocs.Metadata dla Pythona przez .NET (repozytorium wymusza wersję 26.5)
- Plik PSD lub AI do eksperymentów
Instalacja
pip install groupdocs-metadata-net==26.5
Krok 1 – Zrzut całego pakietu XMP
Zacznij od zobaczenia wszystkiego, co plik zawiera. Zrzut przegląda pakiet główny, każdy zarejestrowany schemat i na końcu przeszukuje drzewo właściwości pod kątem wszystkiego niestandardowego, zbierając to wszystko w jedną płaską słownikową strukturę.
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: # właściwości pakietu głównego
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: # przechwycenie własnych pakietów
put(result, p)
Kluczowe punkty:
interpreted_valuenajpierw: daty i wyliczenia pojawiają się w formie czytelnej dla człowieka, a nie w surowej.- Siedem schematów plus przeszukiwanie: końcowy przebieg
find_propertiesłapie pakiety dostawców, które nie zostały objęte nazwanymi schematami. - Jedno otwarcie pliku: cały zrzut kosztuje jedynie jednego kontekstu
Metadata, co ma znaczenie przy masowym ingestowaniu.
Wskazówka: zindeksuj ten słownik w czasie ingestowania, a większość późniejszych pytań o metadane stanie się odwołaniem do słownika zamiast odczytu pliku.
Który schemat XMP powinien najpierw odczytać moja integracja?
Zacznij od Dublin Core. Jego dziewięć pól dc: zawiera tytuł, twórcę, prawa i temat, które większość systemów DAM, indeksów wyszukiwania i kontroli licencji uznaje, a zarówno pliki PSD, jak i AI udostępniają je identycznie. Drugi odczytuj schemat Photoshop, aby uzyskać kontekst redakcyjny, taki jak City, Credit i DateCreated. Pełny przegląd pakietu zostaw na zadania ingestujące, które muszą przechwycić wszystko.
Krok 2 – Odczyt schematów, które odpowiadają na rzeczywiste pytania
W kodzie wywoływanym w czasie żądania ogranicz odczyt do jednego schematu. Dublin Core odpowiada na pytania o własność i wyszukiwanie:
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>"))
Schemat Photoshop działa w ten sam sposób poprzez typowane właściwości: ps.color_mode, ps.icc_profile, ps.city, ps.country, ps.date_created, ps.caption_writer, ps.credit i ps.source, każda odczytywana z zabezpieczeniem przed None. Są to pola, na które filtrują Bridge, Lightroom i wyszukiwarki DAM w plikach Adobe.
Zwróć uwagę, co się dzieje w plikach bez XMP: zabezpieczenia zwracają pusty słownik, a nie wyjątek. Świeżo wyeksportowane zasoby często tak właśnie wyglądają, więc zachowaj tę logikę w swojej integracji.
Te same trzy odczyty działają również w plikach Illustrator. Zamień campaign-hero.psd na brand-mark.ai i nic się nie zmieni, co czyni jedną ścieżkę kodu realistyczną dla mieszanych archiwów Adobe. W praktyce świeży eksport AI zazwyczaj zawiera mniej wypełnionych schematów niż zapis Photoshop, więc ścieżka zwracająca pusty słownik jest tam wykorzystywana częściej.
Krok 3 – Zapis praw autorskich i twórcy
Teraz ścieżka zapisu. Oznaczenie własności dotyka trzech pól, aby każdy czytnik widział tę samą tożsamość: dc:rights jako informacja prawna, dc:creator jako lista uporządkowana oraz xmp:CreatorTool dla narzędzi, które odczytują schemat XmpBasic zamiast Dublin Core. Kiedyś straciłem popołudnie na baner licencyjny wyświetlający „Nieznany autor” w zasobach, które projektanci zapewniali, że są otagowane; wartości znajdowały się w dc:creator, a narzędzie odczytywało tylko xmp:CreatorTool. Zapis obu zakończył tę klasę błędów.
with Metadata("campaign-hero.psd") as metadata:
root = metadata.get_root_package()
xmp = getattr(root, "xmp_package", None)
if xmp is None: # plik nie ma w ogóle 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")
Kluczowe punkty:
- Zabezpieczenia tworzą brakujące warstwy:
XmpPacketWrapperiXmpDublinCorePackagesą tworzone w razie potrzeby, więc zapis działa także w plikach bez XMP. - Tablica ORDERED dla twórców: kolejność autorów ma znaczenie, dlatego lista twórców używa uporządkowanej
XmpArray. - Zapisz pod nową ścieżką: plik źródłowy pozostaje niezmieniony, co jest właściwym domyślnym zachowaniem przy krokach eksportu.
Krok 4 – Oznaczanie słów kluczowych do wyszukiwania
dc:subject to worek słów kluczowych, którego używają indeksy wyszukiwania DAM. Zapis zastępuje cały worek w jednym wywołaniu:
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")
Słowa kluczowe używają tablicy UNORDERED, ponieważ kolejność nie ma znaczenia dla indeksatora. Ponieważ set zastępuje istniejący worek, najpierw odczytaj bieżące słowa kluczowe i połącz je w Pythonie, gdy potrzebujesz dodawania tagów zamiast ich zastępowania.
Aby zweryfikować każdy zapis, ponownie uruchom czytnik z Kroku 2 na pliku wyjściowym. Repozytorium automatyzuje dokładnie to: ponownie odczytuje swoje wyniki i sprawdza, czy ciąg praw autorskich oraz pierwsze słowo kluczowe przetrwały w zapisanych bajtach.
Praktyczne zastosowania
Ingestja DAM
Uruchom zrzut z Kroku 1 na każdym przychodzącym pliku i przechowuj słownik razem z rekordem zasobu. Wyszukiwanie, deduplikacja i kontrole praw potem odbywają się na bazie danych zamiast ponownego otwierania plików binarnych. Zrzut małej próbki PSD z repozytorium już zwraca solidny zestaw właściwości w jednym przebiegu, a to samo wywołanie zachowuje swoją formę, gdy wejściem staje się folder z tysiącami plików.
Egzekwowanie licencji
Zanim zasób trafi do portalu klienta, wymagaj niepustego dc:rights. Pliki, które nie spełniają tego warunku, automatycznie przechodzą przez proces znakowania z Kroku 3, więc nic nie opuszcza systemu bez odpowiedniej informacji.
Masowa zmiana tagów
Gdy zmienia się taksonomia, odczytaj dc:subject każdego pliku, zamapuj stare terminy na nowe w Pythonie i zapisz połączony worek z powrotem przy użyciu Kroku 4. Zarówno archiwa PSD, jak i AI korzystają z tej samej pętli. Nie potrzebujesz licencji Photoshop.
Najlepsze praktyki i wskazówki
- Traktuj pusty jako normalny: pliki bez XMP są rutyną, nie błędem; wzorzec wczesnego zwrotu utrzymuje przepływy w pipeline.
- Scal przed zapisem słów kluczowych:
setzastępujedc:subject, więc dodawanie tagów wymaga odczytu, rozszerzenia i zapisu. - Zapisuj tożsamość w obu schematach: parowanie
dc:creatorzxmp:CreatorToolutrzymuje zgodność czytników Dublin Core i XmpBasic. - Weryfikuj zapisy odczytem zwrotnym: ponowne odczytanie po zapisie jest tanie i natychmiast wykrywa niespodziewane zmiany w kontenerze.
- Licencja na produkcję: tryb ewaluacyjny uruchamia wszystko, co pokazano tutaj; przed znakowaniem rzeczywistych zasobów klientów użyj licencji.
Zakończenie
Odczyt i zapis XMP w plikach Adobe sprowadza się do trzech kroków: rozwiąż pakiet przez get_root_package(), zabezpiecz potrzebny schemat i odczytaj lub zapisz typowane wartości. Dzięki tym krokom zbudowałeś pełny cykl w tym samouczku – od zrzutu pakietu, przez odczyt schematów, po znakowanie praw autorskich i tagowanie słów kluczowych – przy użyciu tego samego kodu dla plików PSD i AI.
Gotowy, aby wdrożyć to w swoim projekcie? Oto kolejne kroki:
- Przeczytaj dokumentację Working with XMP metadata dotyczącą aktualizacji i usuwania pakietów
- Zapoznaj się z integration-focused use case guide opartym na tym samym repozytorium
- Sklonuj sample project i uruchom go na własnych zasobach
Dodatkowe zasoby
- Dokumentacja GroupDocs.Metadata
- Referencja API
- Przykładowe projekty na GitHubie
- Kategoria bloga GroupDocs.Metadata
Masz pytania dotyczące swojego przepływu pracy XMP? Zapytaj na forum wsparcia.