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 chamarDocument.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 chamarRemove()se você não tem certeza de que a anotação ainda está presente;Remove()retornafalseem 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()(ouPdfAnnotationEditor.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
| Problema | Causa | Correção |
|---|---|---|
| Anotação não visível após salvar | A anotação foi construída, mas nunca adicionada a Page.Annotations() | Chame page.Annotations().Add(annotation) antes de doc.Save() |
Remove() retorna false | A referência de anotação fornecida não corresponde a uma entrada atualmente na coleção | Use Contains() primeiro, ou remova por índice com Delete(index) |
| Tipo de anotação incorreto após recarregar | O 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ção | Um PdfAction local saiu do escopo; LinkAnnotation.Action() retorna a cópia clonada da anotação, não o objeto original | Leia 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 efeito | BindPdf() não foi chamado, ou foi chamado com um caminho que não existe | Confirme 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étodo | Descrição |
|---|---|
Annotation | Classe 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 |
AnnotationCollection | Coleçã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 |
TextAnnotation | Anotação em estilo de post-it com Open() e Icon() (TextIcon) |
LinkAnnotation | Regiã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 |
HighlightAnnotation | Marca um trecho de texto com uma cor de destaque |
FreeTextAnnotation | Exibe uma chamada de texto; configurada via Justification(), DefaultAppearanceObject(), Callout() |
CircleAnnotation | Desenha uma elipse dentro do retângulo da anotação |
WatermarkAnnotation | Anotação de sobreposição com um acessador Opacity() / Opacity(value) |
WidgetAnnotation | Anotação de aparência de campo de formulário com ReadOnly(), Required(), Exportable(), DefaultAppearance() |
NamedAction | Ação de navegação predefinida (PredefinedAction enum) anexável a um LinkAnnotation |
JavascriptAction | Executa uma string ECMAScript via Script() / GetECMAScriptString() |
SubmitFormAction | Envia dados de formulário para uma URL FileSpecification via Url() / Url(value) |
Border | Borda da anotação com Width(), Style() (BorderStyle), Effect() (BorderEffect) |
PdfAnnotationEditor | Facade 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 |