Trabalhando com Anotações PDF

Trabalhando com Anotações PDF

Trabalhando com Anotações PDF

As anotações PDF em Aspose.PDF FOSS para C++ são representadas pela classe base Annotation e seus subtipos concretos (TextAnnotation, LinkAnnotation, HighlightAnnotation, FreeTextAnnotation, CircleAnnotation, WatermarkAnnotation, WidgetAnnotation e outros). Cada página expõe suas anotações através de Page.Annotations(), que retorna um AnnotationCollection. Este guia aborda a adição de anotações a uma página, iteração e remoção delas, leitura de anotações de um documento existente, anexação de ações de link, personalização da aparência e achatamento de anotações.


Adicionando Anotações a uma Página

Crie uma instância de anotação concreta, posicione-a com um Rectangle e adicione-a à coleção da página com AnnotationCollection.Add(). TextAnnotation representa um comentário no estilo de nota autoadesiva ancorado a um ponto na página:

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
#include <aspose/pdf/rectangle.hpp>

int main() {
    Aspose::Pdf::Document doc("input.pdf");
    auto& page = doc.Pages()[1];

    Aspose::Pdf::Annotations::TextAnnotation note(doc);
    note.Rect(Aspose::Pdf::Rectangle(100.0, 700.0, 200.0, 720.0, false));
    note.Contents("Reviewed and approved");

    page.Annotations().Add(note);
    doc.Save("annotated.pdf");
}

Annotation.Contents() / Contents(value) obtêm e definem o texto da nota, e Annotation.Rect() / Rect(value) posicionam a anotação na página.


Iterando e Removendo Anotações

AnnotationCollection suporta contagem, acesso indexado, verificações de pertinência e remoção por valor ou por índice:

#include <aspose/pdf/document.hpp>

int main() {
    Aspose::Pdf::Document doc("input.pdf");
    auto& annotations = doc.Pages()[1].Annotations();

    std::cout << "Annotation count: " << annotations.Count() << "\n";

    for (int i = 0; i < annotations.Count(); ++i) {
        std::cout << "Contents: " << annotations[i].Contents() << "\n";
    }

    if (annotations.Count() > 0) {
        annotations.Delete(0);   // remove by index
    }
    annotations.Clear();         // remove everything
}

AnnotationCollection.Contains(annotation) e Remove(annotation) operam em uma referência de anotação específica; Delete(index) remove por posição, e Delete(annotation) remove uma anotação específica sem precisar de seu índice. IsReadOnly() informa se a coleção pode ser modificada.


Lendo Anotações de um Documento Existente

Quando um documento é carregado, suas anotações já estão preenchidas e podem ser inspecionadas sem adicionar nada. Annotation.AnnotationType() informa o subtipo (AnnotationType::Text, AnnotationType::Highlight, AnnotationType::Link, AnnotationType::FreeText, AnnotationType::FileAttachment, AnnotationType::Watermark e outros):

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>

int main() {
    Aspose::Pdf::Document doc("annotated.pdf");
    auto& annotations = doc.Pages()[1].Annotations();

    for (int i = 0; i < annotations.Count(); ++i) {
        auto& a = annotations[i];
        if (a.AnnotationType() == Aspose::Pdf::Annotations::AnnotationType::Text) {
            std::cout << "Note: " << a.Contents() << "\n";
        }
    }
}

A ordem e o subtipo das anotações são preservados durante um ciclo de salvar/recarregar, de modo que o código que indexa Annotations() após carregar um documento vê a mesma sequência que estava presente quando o arquivo foi gravado.


Anotações de Link e Ações

LinkAnnotation anexa uma região clicável a uma página e despacha um PdfAction quando ativado. NamedAction salta para um destino de navegação predefinido, JavascriptAction executa uma string ECMAScript, e SubmitFormAction envia dados de formulário para uma URL via um FileSpecification:

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/link_annotation.hpp>
#include <aspose/pdf/annotations/named_action.hpp>
#include <aspose/pdf/annotations/predefined_action.hpp>
#include <aspose/pdf/rectangle.hpp>

int main() {
    Aspose::Pdf::Document doc;
    auto page = doc.Pages().Add();

    Aspose::Pdf::Annotations::LinkAnnotation link(
        page, Aspose::Pdf::Rectangle(0.0, 0.0, 100.0, 20.0, false));
    link.Action(Aspose::Pdf::Annotations::NamedAction(
        Aspose::Pdf::Annotations::PredefinedAction::LastPage));

    page.Annotations().Add(link);
    doc.Save("linked.pdf");
}

LinkAnnotation.Action(value) aceita qualquer subtipo PdfAction e o clona internamente, de modo que a anotação mantém sua própria cópia da ação. LinkAnnotation.Destination() / Destination(value) definem um destino de navegação explícito em vez de uma ação, e Highlighting() / Highlighting(value) controlam o feedback visual exibido enquanto o link é clicado.


Aparência da Anotação: Borda, Sinais e Cor

Cada Annotation expõe um Border, um campo de bits de AnnotationFlags, e um Color usado para renderizar sua aparência:

#include <aspose/pdf/annotations/border_style.hpp>
#include <aspose/pdf/annotations/annotation_flags.hpp>
#include <aspose/pdf/color.hpp>

// 'note' is an existing Annotation reference, e.g. from AnnotationCollection.
note.Border().Width(2);
note.Border().Style(Aspose::Pdf::Annotations::BorderStyle::Dashed);
note.Flags(Aspose::Pdf::Annotations::AnnotationFlags::Print);
note.Color(Aspose::Pdf::Color::Red());

Border.Style() aceita BorderStyle::Solid, Dashed, Beveled, Inset ou Underline. Border.Effect() também oferece suporte a um contorno BorderEffect::Cloudy com EffectIntensity() controlando o quão pronunciado ele é. AnnotationFlags é um campo de bits — combine valores como Print, NoZoom, ReadOnly e LockedContents para controlar como uma anotação se comporta em um visualizador sem alterar seu conteúdo visível.


Aplainamento de Anotações

Uma única anotação pode ser aplainada — mesclada ao conteúdo da página e tornada não interativa — chamando Annotation.Flatten() diretamente:

#include <aspose/pdf/document.hpp>

int main() {
    Aspose::Pdf::Document doc("annotated.pdf");
    auto& annotations = doc.Pages()[1].Annotations();
    for (int i = 0; i < annotations.Count(); ++i) {
        annotations[i].Flatten();
    }
    doc.Save("flattened.pdf");
}

Para operações de anotação em todo o documento, PdfAnnotationEditor segue o padrão Facade compartilhado usado em todo o API: vincule um documento fonte com BindPdf(), aplique uma ou mais operações de anotação e, em seguida, grave o resultado com Save():

#include <aspose/pdf/facades/pdf_annotation_editor.hpp>

int main() {
    Aspose::Pdf::Facades::PdfAnnotationEditor editor;
    editor.BindPdf("annotated.pdf");
    editor.FlatteningAnnotations();
    editor.Save("flattened.pdf");
}

PdfAnnotationEditor.DeleteAnnotations() remove todas as anotações do documento vinculado; DeleteAnnotations(annotType) restringe a remoção a um único AnnotationType. ImportAnnotationsFromXfdf(xfdfFile) e ImportAnnotationsFromFdf(fdfFile) carregam dados de anotação exportados de outro visualizador de PDF.


Dicas e Melhores Práticas

  • Sempre adicione uma anotação recém-construída a Page.Annotations() antes de chamar Document.Save() — uma anotação que nunca é adicionada a uma coleção não é gravada no arquivo de saída.
  • Use AnnotationCollection.Contains(annotation) antes de chamar Remove() se você não tem certeza de que a anotação ainda está presente; Remove() retorna false em vez de lançar uma exceção quando a anotação está ausente.
  • Verifique Annotation.AnnotationType() antes de fazer cast ou ramificar com base no comportamento do subtipo ao iterar anotações carregadas de um arquivo PDF não confiável ou de terceiros.
  • Aplane as anotações com Annotation.Flatten() (ou PdfAnnotationEditor.FlatteningAnnotations() para o documento inteiro) antes de arquivar um documento, para que revisores em outras ferramentas vejam a mesma aparência que você criou.
  • AnnotationFlags é um campo de bits — combine as flags com os valores inteiros subjacentes do enum em vez de supor que apenas uma flag pode estar ativa de cada vez.

Problemas Comuns

ProblemaCausaCorreção
Anotação não visível após salvarA anotação foi construída, mas nunca adicionada a Page.Annotations()Chame page.Annotations().Add(annotation) antes de doc.Save()
Remove() retorna falseA referência de anotação fornecida não corresponde a uma entrada atualmente na coleçãoUse Contains() primeiro, ou remova por índice com Delete(index)
Tipo de anotação incorreto após recarregarO código assumiu um subtipo específico sem verificar AnnotationType()Faça a ramificação em Annotation.AnnotationType() antes de tratar o objeto como um subtipo específico
A ação de link parece não estar definida após a atribuiçãoUm PdfAction local saiu do escopo; LinkAnnotation.Action() retorna a cópia clonada da anotação, não o objeto originalLeia a ação de volta através de link.Action() em vez de manter a variável local original
A operação PdfAnnotationEditor não tem efeitoBindPdf() não foi chamado, ou foi chamado com um caminho que não existeConfirme que BindPdf() tem sucesso antes de chamar FlatteningAnnotations() ou DeleteAnnotations()

FAQ

Como adiciono uma anotação no estilo de comentário a uma página PDF?

Construa um TextAnnotation com o Document de destino, defina seu Rect() e Contents(), e então adicione-o a page.Annotations() antes de salvar.

Como descubro que tipo de anotação estou visualizando?

Chame Annotation.AnnotationType(), que devolve um valor enum AnnotationType como Text, Link, Highlight, FreeText, FileAttachment ou Watermark.

Uma anotação pode conter mais de um sinalizador?

Sim. AnnotationFlags é um bitfield (Default, Invisible, Hidden, Print, NoZoom, ReadOnly, LockedContents e outros), portanto múltiplos sinalizadores podem ser combinados em uma única anotação.

Qual é a diferença entre achatar uma anotação e achatar um documento?

Annotation.Flatten() mescla uma única anotação ao conteúdo da sua página. PdfAnnotationEditor.FlatteningAnnotations() (opcionalmente limitado por intervalo de páginas e AnnotationType via a sobrecarga que aceita start, end e annotType) achata todo o documento vinculado em uma única chamada.

Como removo todas as anotações de um determinado tipo de um documento?

Vincule o documento com PdfAnnotationEditor.BindPdf(), chame DeleteAnnotations(annotType) com o AnnotationType alvo, então Save() o resultado.


API Reference Resumo

Classe/MétodoDescrição
AnnotationClasse base abstrata para todos os subtipos de anotação PDF
Annotation.Rect() / Rect(value)Obtenha ou defina o retângulo delimitador da anotação
Annotation.Contents() / Contents(value)Obtenha ou defina o conteúdo de texto da anotação
Annotation.AnnotationType()Retorna o valor enum AnnotationType para esta anotação
Annotation.Flags() / Flags(value)Obtenha ou defina o bitfield AnnotationFlags
Annotation.Border() / Border(value)Obtém ou define o Border da anotação
Annotation.Color() / Color(value)Obtém ou define a exibição da anotação Color
Annotation.Flatten()Mescla esta anotação ao conteúdo da página, tornando-a não interativa
AnnotationCollectionColeção ordenada de anotações em uma página, retornada por Page.Annotations()
AnnotationCollection.Add(annotation) / Add(annotation, considerRotation)Adiciona uma anotação à coleção
AnnotationCollection.Count()Retorna o número de anotações na coleção
AnnotationCollection.Contains(annotation)Informa se a coleção contém a anotação fornecida
AnnotationCollection.Remove(annotation)Remove uma anotação específica; retorna false se não for encontrada
AnnotationCollection.Delete(index) / Delete(annotation)Remove uma anotação por índice ou por referência
AnnotationCollection.Clear()Remove todas as anotações da coleção
TextAnnotationAnotação em estilo de post-it com Open() e Icon() (TextIcon)
LinkAnnotationRegião clicável enviando um PdfAction via Action() / Action(value)
LinkAnnotation.Destination() / Destination(value)Obtém ou define um destino de navegação explícito
HighlightAnnotationMarca um trecho de texto com uma cor de destaque
FreeTextAnnotationExibe uma chamada de texto; configurada via Justification(), DefaultAppearanceObject(), Callout()
CircleAnnotationDesenha uma elipse dentro do retângulo da anotação
WatermarkAnnotationAnotação de sobreposição com um acessador Opacity() / Opacity(value)
WidgetAnnotationAnotação de aparência de campo de formulário com ReadOnly(), Required(), Exportable(), DefaultAppearance()
NamedActionAção de navegação predefinida (PredefinedAction enum) anexável a um LinkAnnotation
JavascriptActionExecuta uma string ECMAScript via Script() / GetECMAScriptString()
SubmitFormActionEnvia dados de formulário para uma URL FileSpecification via Url() / Url(value)
BorderBorda da anotação com Width(), Style() (BorderStyle), Effect() (BorderEffect)
PdfAnnotationEditorFacade para importação, modificação, achatamento e exclusão de anotações em todo o documento
PdfAnnotationEditor.FlatteningAnnotations()Achatamento de anotações ao longo do documento vinculado
PdfAnnotationEditor.DeleteAnnotations(annotType)Exclui todas as anotações de um determinado AnnotationType
PdfAnnotationEditor.ImportAnnotationsFromXfdf(xfdfFile)Importa anotações de um arquivo XFDF

Ver também

 Português