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)  # False

Nomeando 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 remaining

Gerando 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)  # 2

Subtipos 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 AnnotationType em 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 de properties totalmente.
  • Gere aparências em lote com AnnotationCollection.generate_appearances em vez de percorrer generate_appearance() por anotação; ele devolve a contagem real gerada para que você possa detectar subtipos ignorados/não suportados.
  • delete() e indexação em page.annotations são ambos baseados em zero; valide um índice antes de chamar delete() se ele vier de entrada do usuário, pois um índice fora do intervalo gera IndexError.
  • Envolva valores de nome PDF (como o Stamp’s Name) em AnnotationName para que eles circulem como nomes PDF em vez de strings de texto simples.

Problemas comuns

ProblemaCausaCorreção
generate_appearances() retorna menos do que o número de anotações adicionadasUm ou mais subtipos não têm renderizador de aparência embutidoVerifique 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 IndexErrorO índice é negativo ou está além da contagem atual de anotaçõesVerifique len(page.annotations) antes de chamar delete()
Uma propriedade definida com set_property() não aparece após recarregarA propriedade foi definida como None, o que a exclui em vez de armazená-laUse 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çãoVerifique 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étodoDescrição
AnnotationCollection.addCriar e anexar uma nova anotação a uma página
AnnotationCollection.insertCriar e inserir uma nova anotação em um índice específico
AnnotationCollection.deleteRemover uma anotação por índice (levanta IndexError se estiver fora do intervalo)
AnnotationCollection.clearRemover todas as anotações da página
AnnotationCollection.generate_appearancesGere fluxos de aparência /AP /N para cada anotação suportada na página
Annotation.get_property / set_propertyLeia ou escreva um valor de propriedade específico de subtipo
Annotation.update_propertiesRecalcule o estado derivado após edições diretas de propriedades
Annotation.generate_appearanceGere o fluxo de aparência /AP /N para uma única anotação
AnnotationTypeEnumeração dos nomes padrão de subtipos de anotação PDF
AnnotationFlagsIntFlag do comportamento de exibição/interação da anotação
AnnotationNamestr subclasse que marca um valor para serializar como um nome PDF
PDF3DAnnotation / PDF3DArtwork / PDF3DContent / PDF3DViewModelo de anotação 3D e obra de arte em pré-lançamento
PDF3DRenderMode / PDF3DLightingSchemeEnums para modo de renderização de visualização 3D e esquema de iluminação

Ver também

 Português