Anotações PDF
Anotações PDF
Page.annotations expõe um AnnotationCollection — uma visualização mutável, semelhante a uma sequência, de todas as anotações em uma página. Cada entrada é um Annotation (ou as subclasses MarkupAnnotation / LinkAnnotation), e dados específicos de subtipo, como pontos de quad, listas de tinta ou cores, são lidos e gravados através de get_property() / set_property() ao invés de atributos dedicados.
Adicionando Anotações
AnnotationCollection.add(subtype, rect, contents, title, appearance_normal, properties) cria uma nova anotação e a acrescenta à página. subtype aceita tanto uma string simples ("Text", "Square", "Highlight") quanto um membro enum AnnotationType.
import aspose_pdf
from aspose_pdf import Document, AnnotationType
doc = Document()
doc.pages.add()
page = doc.pages[0]
# Plain string subtype
page.annotations.add("Text", (100, 100, 200, 200), "Hello")
# AnnotationType enum, with subtype-specific properties
page.annotations.add(
AnnotationType.POLYGON,
(0, 0, 10, 10),
"",
properties={"Vertices": [0, 0, 10, 0, 5, 10]},
)Lendo e Atualizando Propriedades
get_property(name, default) lê um valor específico de subtipo; set_property(name, value) grava um, e definir uma propriedade como None a remove do dicionário properties da anotação.
doc = Document()
doc.pages.add()
page = doc.pages[0]
ann = page.annotations.add(
"Square", (0, 0, 50, 50), "x", properties={"C": [1, 0, 0]},
)
ann.set_property("IC", [0, 0, 1])
print(page.annotations[0].get_property("IC")) # [0, 0, 1]
ann.set_property("C", None) # removes the "C" entry entirely
print("C" in page.annotations[0].properties) # FalseNomeando Anotações com AnnotationName
Nomes PDF (por exemplo, a entrada Name de uma anotação Stamp) são marcados distintamente de strings simples usando AnnotationName, uma subclasse str de aspose_pdf.engine.cos. Um valor armazenado dessa forma ainda é comparado como igual a uma string comum.
from aspose_pdf.engine.cos import AnnotationName
doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add(
"Stamp", (10, 10, 110, 60), "",
properties={"Name": AnnotationName("Approved")},
)Inserindo, Excluindo e Limpando
insert(index, subtype, rect, contents, title, appearance_normal, properties) coloca uma nova anotação em uma posição específica; delete(index) remove uma por índice (gerando IndexError para um índice fora do intervalo); clear() remove todas as anotações da página.
doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add("Text", (0, 0, 100, 100), "A")
page.annotations.add("Text", (200, 200, 300, 300), "C")
page.annotations.insert(1, "Text", (100, 100, 200, 200), "B")
# order is now: A, B, C
page.annotations.delete(1) # removes "B"
page.annotations.clear() # removes everything remainingGerando Aparências de Anotações
Annotation.generate_appearance(force) constrói o fluxo de aparência /AP /N para uma anotação e retorna True quando existe um renderizador para esse subtipo; AnnotationCollection.generate_appearances(force) faz o mesmo para cada anotação na página em uma única chamada e retorna a contagem de anotações que foram realmente geradas (subtipos não suportados são ignorados).
doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add("Square", (0, 0, 50, 50), "")
page.annotations.add("Circle", (60, 0, 110, 50), "")
page.annotations.add("Text", (0, 60, 20, 80), "") # unsupported subtype -> skipped
generated = page.annotations.generate_appearances()
print(generated) # 2Subtipos de Anotação e Flags
AnnotationType enumera os nomes de subtipos padrão do PDF 32000-1:2008 (Tabela 169): TEXT, LINK, FREE_TEXT, LINE, SQUARE, CIRCLE, POLYGON, POLY_LINE, HIGHLIGHT, UNDERLINE, SQUIGGLY, STRIKE_OUT, STAMP, CARET, INK, POPUP, FILE_ATTACHMENT, SOUND, MOVIE, WIDGET, SCREEN, PRINTER_MARK, TRAP_NET, WATERMARK e REDACT.
AnnotationFlags é um IntFlag que abrange o comportamento de exibição/ interação de anotações: DEFAULT, INVISIBLE, HIDDEN, PRINT, NO_ZOOM, NO_ROTATE, NO_VIEW, READ_ONLY, LOCKED e TOGGLE_NO_VIEW.
Pré-lançamento: Anotações 3D
PDF3DAnnotation, PDF3DArtwork, PDF3DContent e PDF3DView modelam arte 3D anexada a uma página — um PDF3DAnnotation tem um rect: Rectangle, um artwork: PDF3DArtwork e um background_color: Color opcional. PDF3DArtwork.add_view() registra um PDF3DView, cada um carregando um render_mode (PDF3DRenderMode: SOLID, WIREFRAME, TRANSPARENT) e um lighting_scheme (PDF3DLightingScheme: HEADLAMP, WHITE, GRAY, DARK, CUSTOM). A docstring da própria biblioteca marca PDF3DAnnotation como um “wrapper de anotação mínima para importações pré-lançamento” — trate esta superfície como em estágio inicial, e não como um API de autoria 3D totalmente desenvolvido.
Dicas e Melhores Práticas
- Prefira membros enum
AnnotationTypeem vez de strings de subtipo bruto quando o valor também precisar ser comparado ou usado em ramificações em outra parte do seu código. - Chame
set_property(name, None)para remover uma propriedade completamente em vez de deixar um valor obsoleto no lugar — a entrada desaparece depropertiestotalmente. - Gere aparências em lote com
AnnotationCollection.generate_appearancesem vez de percorrergenerate_appearance()por anotação; ele devolve a contagem real gerada para que você possa detectar subtipos ignorados/não suportados. delete()e indexação empage.annotationssão ambos baseados em zero; valide um índice antes de chamardelete()se ele vier de entrada do usuário, pois um índice fora do intervalo geraIndexError.- Envolva valores de nome PDF (como o
Stamp’sName) emAnnotationNamepara que eles circulem como nomes PDF em vez de strings de texto simples.
Problemas comuns
| Problema | Causa | Correção |
|---|---|---|
generate_appearances() retorna menos do que o número de anotações adicionadas | Um ou mais subtipos não têm renderizador de aparência embutido | Verifique a contagem de retorno em relação a len(page.annotations); subtipos não suportados são ignorados silenciosamente, não geram erro |
delete(index) levanta IndexError | O índice é negativo ou está além da contagem atual de anotações | Verifique len(page.annotations) antes de chamar delete() |
Uma propriedade definida com set_property() não aparece após recarregar | A propriedade foi definida como None, o que a exclui em vez de armazená-la | Use um valor real, não None, quando a propriedade deve persistir |
| A anotação inserida acaba na posição errada | Índice insert(index, ...) contado a partir do estado da coleção antes da inserção | Verifique novamente os índices após cada chamada insert() em um loop |
FAQ
Como adiciono uma anotação de comentário em texto simples?
Chame page.annotations.add("Text", (x0, y0, x1, y1), "comment text"). A tupla de quatro números é o retângulo da anotação na página.
Qual é a diferença entre Annotation, MarkupAnnotation e LinkAnnotation?
Annotation é a visualização ao vivo retornada para qualquer anotação em uma página. MarkupAnnotation é a base para subtipos no estilo markup (realces, notas de texto, formas) e LinkAnnotation é mantido para anotações no estilo de link; ambos atualmente expõem a mesma superfície de método/propriedade que Annotation.
Posso remover uma única propriedade sem excluir a anotação inteira?
Sim — chame annotation.set_property(name, None); a própria anotação permanece intacta, apenas essa entrada é removida de properties.
O AnnotationCollection.generate_appearances falha se um subtipo não for suportado?
Não. Ele ignora subtipos sem um renderizador de aparência embutido e devolve a contagem de anotações para as quais realmente gerou uma aparência.
As classes de anotação 3D estão prontas para produção?
PDF3DAnnotation e tipos relacionados são documentados como um wrapper mínimo para importações pré-lançamento — verifique o comportamento no visualizador de PDF alvo antes de confiar neles para conteúdo 3D de produção.
API Reference Resumo
| Classe/Método | Descrição |
|---|---|
AnnotationCollection.add | Criar e anexar uma nova anotação a uma página |
AnnotationCollection.insert | Criar e inserir uma nova anotação em um índice específico |
AnnotationCollection.delete | Remover uma anotação por índice (levanta IndexError se estiver fora do intervalo) |
AnnotationCollection.clear | Remover todas as anotações da página |
AnnotationCollection.generate_appearances | Gere fluxos de aparência /AP /N para cada anotação suportada na página |
Annotation.get_property / set_property | Leia ou escreva um valor de propriedade específico de subtipo |
Annotation.update_properties | Recalcule o estado derivado após edições diretas de propriedades |
Annotation.generate_appearance | Gere o fluxo de aparência /AP /N para uma única anotação |
AnnotationType | Enumeração dos nomes padrão de subtipos de anotação PDF |
AnnotationFlags | IntFlag do comportamento de exibição/interação da anotação |
AnnotationName | str subclasse que marca um valor para serializar como um nome PDF |
PDF3DAnnotation / PDF3DArtwork / PDF3DContent / PDF3DView | Modelo de anotação 3D e obra de arte em pré-lançamento |
PDF3DRenderMode / PDF3DLightingScheme | Enums para modo de renderização de visualização 3D e esquema de iluminação |