Exemplo completo funcionando disponível no GitHub:
manage-xmp-in-psd-and-ai-files-python
Introdução
Uma equipe de marketing envia 400 arquivos PSD para sua plataforma de ativos. O upload funciona. A busca não, porque nenhum dos arquivos contém palavras‑chave, metade não tem aviso de direitos autorais e os nomes dos designers vivem apenas em uma planilha em algum lugar. A solução não é uma planilha maior. O gerenciamento de XMP é um recurso do GroupDocs.Metadata para Python via .NET que lê e grava o pacote de metadados embutido em arquivos Photoshop PSD e Illustrator AI, o que significa que propriedade e dados de busca podem viver nos próprios arquivos.
XMP é um pacote XML dentro de um contêiner binário, organizado em esquemas: Dublin Core para os campos que todo sistema entende, o esquema Photoshop para contexto editorial, XmpBasic para identidade da ferramenta. Analisar um PSD manualmente para alcançar esse pacote é realmente difícil. Com a classe Metadata são três buscas de atributo, e o mesmo código serve para arquivos AI.
Este tutorial percorre a viagem completa em quatro etapas: capturar instantaneamente todo o pacote, ler os esquemas que importam, gravar direitos autorais e criador, e marcar palavras‑chave para busca. Cada trecho vem de um repositório executável que verifica se os valores gravados persistem.
Pré-requisitos
Antes de começar, certifique‑se de que você tem:
- Python 3 com pip
- GroupDocs.Metadata para Python via .NET (o repositório fixa a versão 26.5)
- Um arquivo PSD ou AI para experimentar
Instalação
pip install groupdocs-metadata-net==26.5
Etapa 1 - Captura instantânea de todo o pacote XMP
Comece vendo tudo que o arquivo contém. A captura percorre o pacote raiz, cada esquema registrado e, por fim, varre a árvore de propriedades em busca de algo não‑padrão, coletando tudo em um único dicionário plano.
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: # propriedades do pacote raiz
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: # captura pacotes personalizados
put(result, p)
Pontos principais:
interpreted_valueprimeiro: datas e enumerações chegam legíveis ao invés de brutas.- Sete esquemas mais uma varredura: a passagem final
find_propertiescaptura pacotes de fornecedores que os esquemas nomeados perdem. - Um arquivo aberto: toda a captura custa um único contexto
Metadata, o que importa em ingestões em massa.
Dica: indexe este dicionário no momento da ingestão e a maioria das perguntas de metadados posteriores se tornarão buscas em dicionário em vez de leituras de arquivo.
Qual esquema XMP minha integração deve ler primeiro?
Comece com Dublin Core. Seus nove campos dc: carregam título, criador, direitos e assunto, valores que a maioria dos sistemas DAM, índices de busca e verificações de licenciamento concordam, e tanto arquivos PSD quanto AI os expõem de forma idêntica. Leia o esquema Photoshop em segundo lugar para contexto editorial como City, Credit e DateCreated. Deixe a varredura de pacote completo para trabalhos de ingestão que precisam capturar tudo.
Etapa 2 - Ler os esquemas que respondem a perguntas reais
Para código em tempo de requisição, limite a leitura a um esquema. Dublin Core responde a questões de propriedade e busca:
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>"))
O esquema Photoshop funciona da mesma forma através de propriedades tipadas: ps.color_mode, ps.icc_profile, ps.city, ps.country, ps.date_created, ps.caption_writer, ps.credit e ps.source, cada uma lida com proteção contra None. Esses são os campos que o Bridge, Lightroom e filtros de busca DAM utilizam para arquivos Adobe.
Observe o que acontece em arquivos sem XMP: as proteções produzem um dicionário vazio, não uma exceção. Ativos exportados recentemente tornam esse caso rotineiro, portanto mantenha esse comportamento na sua integração.
Os mesmos três acessos funcionam em arquivos Illustrator. Troque campaign-hero.psd por brand-mark.ai e nada mais muda, o que torna um único caminho de código realista para arquivos Adobe mistos. Na prática, uma exportação AI fresca costuma chegar com menos esquemas preenchidos que um salvamento Photoshop, então o caminho de dicionário vazio é exercitado com mais frequência lá.
Etapa 3 - Escrever direitos autorais e criador
Agora o caminho de escrita. A marcação de propriedade toca três campos para que todo leitor veja a mesma identidade: dc:rights para o aviso legal, dc:creator como lista ordenada e xmp:CreatorTool para ferramentas que leem o esquema XmpBasic ao invés de Dublin Core. Uma vez perdi uma tarde com um banner de licenciamento mostrando “Autor desconhecido” em ativos que os designers juravam estar marcados; os valores estavam em dc:creator enquanto a ferramenta lia apenas xmp:CreatorTool. Escrever ambos acabou com essa classe de bug.
with Metadata("campaign-hero.psd") as metadata:
root = metadata.get_root_package()
xmp = getattr(root, "xmp_package", None)
if xmp is None: # arquivo não tem XMP nenhum
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")
Pontos principais:
- Proteções criam camadas ausentes:
XmpPacketWrappereXmpDublinCorePackagesão criados sob demanda, então a gravação funciona em arquivos sem XMP. - Array ORDERED para criadores: a ordem do autor tem significado, por isso a lista de criadores usa um
XmpArrayordenado. - Salvar em novo caminho: o arquivo fonte permanece intacto, que é o padrão correto para etapas de exportação.
Etapa 4 - Marcar palavras‑chave para pesquisa
dc:subject é o saco de palavras‑chave dos índices de busca DAM. A gravação substitui todo o saco em uma única chamada:
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")
Palavras‑chave usam um array UNORDERED porque a ordem não importa para um indexador. E como set substitui o saco existente, leia as palavras‑chave atuais primeiro e mescle em Python quando precisar de marcação aditiva em vez de substituição.
Para verificar qualquer gravação, execute novamente o leitor da Etapa 2 contra o arquivo de saída. O repositório automatiza exatamente isso: ele relê suas saídas e verifica se a string de direitos autorais e a primeira palavra‑chave permanecem nos bytes gravados.
Aplicações do mundo real
Ingestão DAM
Execute a captura da Etapa 1 em cada arquivo recebido e armazene o dicionário ao lado do registro de ativo. Busca, deduplicação e verificações de direitos então rodam contra seu banco de dados ao invés de reabrir arquivos binários. A captura da pequena amostra PSD do repositório já devolve um conjunto saudável de propriedades em uma passagem, e a mesma chamada mantém sua forma quando a entrada se torna uma pasta com milhares de arquivos.
Aplicação de licenças
Antes que um ativo seja enviado a um portal de cliente, exija um dc:rights não vazio. Arquivos que falharem recebem automaticamente o tratamento de marcação da Etapa 3, de modo que nada sai sem um aviso.
Reetiquetagem em lote
Quando a taxonomia mudar, leia o dc:subject de cada arquivo, mapeie termos antigos para novos em Python e grave o saco mesclado de volta com a Etapa 4. Tanto arquivos PSD quanto AI seguem o mesmo loop. Nenhuma licença do Photoshop é necessária.
Melhores práticas e dicas
- Trate vazio como normal: arquivos sem XMP são rotineiros, não erros; o padrão de retorno antecipado mantém os pipelines fluindo.
- Mescle antes de gravar palavras‑chave:
setsubstituidc:subject, então marcação aditiva significa ler, estender, gravar. - Grave identidade em ambos os esquemas: parear
dc:creatorcomxmp:CreatorToolmantém leitores Dublin Core e XmpBasic em concordância. - Verifique gravações com leitura de retorno: uma releitura após salvar é barata e captura surpresas do contêiner imediatamente.
- Licença para produção: o modo de avaliação executa tudo o que é mostrado aqui; use uma licença antes de marcar ativos reais de clientes.
Conclusão
Ler e gravar XMP em arquivos Adobe reduz‑se a três passos: resolver o pacote através de get_root_package(), proteger o esquema que você precisa e ler ou gravar valores tipados. Com esses passos você construiu uma viagem completa neste tutorial, da captura do pacote à leitura de esquemas, marcação de direitos autorais e etiquetagem de palavras‑chave, com o mesmo código servindo arquivos PSD e AI.
Pronto para implementar isso no seu projeto? Aqui estão alguns próximos passos:
- Leia a Trabalhando com metadados XMP para atualizar e remover pacotes
- Siga o guia de caso de uso focado em integração construído sobre o mesmo repositório
- Clone o projeto de exemplo e execute-o contra seus próprios ativos
Recursos adicionais
- Documentação do GroupDocs.Metadata
- Referência da API
- Projetos de exemplo no GitHub
- Categoria do blog GroupDocs.Metadata
Perguntas sobre seu fluxo de trabalho XMP? Pergunte no fórum de suporte.