Trabajando con anotaciones PDF
Trabajando con anotaciones PDF
Las anotaciones PDF en Aspose.PDF FOSS for C++ se representan mediante la clase base Annotation y sus subtipos concretos (TextAnnotation, LinkAnnotation, HighlightAnnotation, FreeTextAnnotation, CircleAnnotation, WatermarkAnnotation, WidgetAnnotation y otros). Cada página expone sus anotaciones a través de Page.Annotations(), que devuelve un AnnotationCollection. Esta guía cubre cómo añadir anotaciones a una página, iterar y eliminarlas, leer anotaciones de un documento existente, adjuntar acciones de enlace, personalizar su apariencia y aplanar las anotaciones.
Añadiendo anotaciones a una página
Cree una instancia concreta de anotación, posicionela con un Rectangle y agréguela a la colección de la página con AnnotationCollection.Add(). TextAnnotation representa un comentario al estilo de nota adhesiva anclado a un punto de la 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) obtienen y establecen el texto de la nota, y Annotation.Rect() / Rect(value) posicionan la anotación en la página.
Iterando y eliminando anotaciones
AnnotationCollection admite conteo, acceso indexado, verificaciones de pertenencia y eliminación por valor o 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) y Remove(annotation) operan sobre una referencia de anotación específica; Delete(index) elimina por posición, y Delete(annotation) elimina una anotación específica sin necesitar su índice. IsReadOnly() informa si la colección puede ser modificada.
Leyendo anotaciones de un documento existente
Cuando se carga un documento, sus anotaciones ya están pobladas y pueden inspeccionarse sin añadir nada. Annotation.AnnotationType() informa el subtipo (AnnotationType::Text, AnnotationType::Highlight, AnnotationType::Link, AnnotationType::FreeText, AnnotationType::FileAttachment, AnnotationType::Watermark, y otros):
#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";
}
}
}El orden y el subtipo de las anotaciones se conservan a través de un ciclo de guardado/carga, de modo que el código que indexa en Annotations() después de cargar un documento ve la misma secuencia que estaba presente cuando se escribió el archivo.
Anotaciones de enlace y acciones
LinkAnnotation adjunta una región clicable a una página y despacha un PdfAction cuando se activa. NamedAction salta a un objetivo de navegación predefinido, JavascriptAction ejecuta una cadena ECMAScript, y SubmitFormAction envía datos de formulario a una URL mediante un 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) acepta cualquier subtipo PdfAction y lo clona internamente, de modo que la anotación conserva su propia copia de la acción. LinkAnnotation.Destination() / Destination(value) establecen un objetivo de navegación explícito en lugar de una acción, y Highlighting() / Highlighting(value) controlan la retroalimentación visual mostrada mientras se hace clic en el enlace.
Apariencia de la anotación: borde, banderas y color
Cada Annotation expone un Border, un bitfield de AnnotationFlags, y un Color usado para renderizar su apariencia:
#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() acepta BorderStyle::Solid, Dashed, Beveled, Inset o Underline. Border.Effect() también admite un contorno BorderEffect::Cloudy con EffectIntensity() que controla cuán pronunciado es. AnnotationFlags es un bitfield — combine valores como Print, NoZoom, ReadOnly y LockedContents para controlar cómo se comporta una anotación en un visor sin cambiar su contenido visible.
Aplanado de Anotaciones
Una sola anotación puede aplanarse — fusionarse con el contenido de la página y volverse no interactiva — llamando a Annotation.Flatten() directamente:
#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 operaciones de anotación a nivel de documento, PdfAnnotationEditor sigue el patrón compartido Facade usado en todo el API: vincule un documento fuente con BindPdf(), aplique una o más operaciones de anotación, y luego escriba el resultado con 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() elimina todas las anotaciones del documento enlazado; DeleteAnnotations(annotType) restringe la eliminación a una sola AnnotationType. ImportAnnotationsFromXfdf(xfdfFile) y ImportAnnotationsFromFdf(fdfFile) cargan datos de anotación exportados desde otro visor PDF.
Consejos y Mejores Prácticas
- Siempre agregue una anotación recién construida a
Page.Annotations()antes de llamar aDocument.Save()— una anotación que nunca se agrega a una colección no se escribe en el archivo de salida. - Use
AnnotationCollection.Contains(annotation)antes de llamar aRemove()si no está seguro de que la anotación siga presente;Remove()devuelvefalseen lugar de lanzar una excepción cuando la anotación está ausente. - Compruebe
Annotation.AnnotationType()antes de convertir o ramificar según el comportamiento del subtipo al iterar anotaciones cargadas desde un archivo PDF no confiable o de terceros. - Aplane las anotaciones con
Annotation.Flatten()(oPdfAnnotationEditor.FlatteningAnnotations()para todo el documento) antes de archivar un documento para que los revisores en otras herramientas vean la misma apariencia que usted creó. AnnotationFlagses un campo de bits — combine los indicadores con los valores enteros subyacentes del enum en lugar de asumir que solo una bandera puede estar activa a la vez.
Problemas comunes
| Problema | Causa | Corrección |
|---|---|---|
| Anotación no visible después de guardar | La anotación se construyó pero nunca se añadió a Page.Annotations() | Llame a page.Annotations().Add(annotation) antes de doc.Save() |
Remove() devuelve false | La referencia de anotación proporcionada no coincide con ninguna entrada actualmente en la colección | Use Contains() primero, o elimine por índice con Delete(index) |
| Tipo de anotación incorrecto después de recargar | El código asumió un subtipo específico sin comprobar AnnotationType() | Ramifique en Annotation.AnnotationType() antes de tratar el objeto como un subtipo específico |
| La acción del enlace parece no estar establecida después de la asignación | Una PdfAction local salió del alcance; LinkAnnotation.Action() devuelve la copia clonada de la anotación, no el objeto original | Lea la acción nuevamente a través de link.Action() en lugar de mantener la variable local original |
La operación PdfAnnotationEditor no tiene efecto | BindPdf() no fue llamado, o fue llamado con una ruta que no existe | Confirme que BindPdf() tenga éxito antes de llamar a FlatteningAnnotations() o DeleteAnnotations() |
FAQ
¿Cómo añado una anotación de estilo comentario a una página PDF?
Construya un TextAnnotation con el Document objetivo, establezca su Rect() y Contents(), y luego añádalo a page.Annotations() antes de guardar.
¿Cómo descubro qué tipo de anotación estoy viendo?
Llame a Annotation.AnnotationType(), que devuelve un valor enum AnnotationType como Text, Link, Highlight, FreeText, FileAttachment o Watermark.
¿Puede una anotación contener más de una bandera?
Sí. AnnotationFlags es un campo de bits (Default, Invisible, Hidden, Print, NoZoom, ReadOnly, LockedContents, y otros), por lo que varias banderas pueden combinarse en una sola anotación.
¿Cuál es la diferencia entre aplanar una anotación y aplanar un documento?
Annotation.Flatten() fusiona una única anotación con el contenido de su página. PdfAnnotationEditor.FlatteningAnnotations() (opcionalmente delimitado por un rango de páginas y AnnotationType mediante la sobrecarga que acepta start, end y annotType) aplana todo el documento enlazado en una sola llamada.
¿Cómo elimino todas las anotaciones de un tipo de un documento?
Vincule el documento con PdfAnnotationEditor.BindPdf(), llame a DeleteAnnotations(annotType) con el AnnotationType objetivo, luego Save() el resultado.
API Reference Resumen
| Clase/Método | Descripción |
|---|---|
Annotation | Clase base abstracta para todos los subtipos de anotaciones PDF |
Annotation.Rect() / Rect(value) | Obtener o establecer el rectángulo delimitador de la anotación |
Annotation.Contents() / Contents(value) | Obtiene o establece el contenido de texto de la anotación |
Annotation.AnnotationType() | Devuelve el valor enum AnnotationType de esta anotación |
Annotation.Flags() / Flags(value) | Obtener o establecer el campo de bits AnnotationFlags |
Annotation.Border() / Border(value) | Obtenga o establezca el Border de la anotación |
Annotation.Color() / Color(value) | Obtener o establecer la visualización de la anotación Color |
Annotation.Flatten() | Fusiona esta anotación con el contenido de la página, haciéndola no interactiva |
AnnotationCollection | Colección ordenada de anotaciones en una página, devuelta por Page.Annotations() |
AnnotationCollection.Add(annotation) / Add(annotation, considerRotation) | Añade una anotación a la colección |
AnnotationCollection.Count() | Devuelve el número de anotaciones en la colección |
AnnotationCollection.Contains(annotation) | Indica si la colección contiene la anotación dada |
AnnotationCollection.Remove(annotation) | Elimina una anotación específica; devuelve false si no se encuentra |
AnnotationCollection.Delete(index) / Delete(annotation) | Elimina una anotación por índice o por referencia |
AnnotationCollection.Clear() | Elimina todas las anotaciones de la colección |
TextAnnotation | Anotación estilo nota adhesiva con Open() y Icon() (TextIcon) |
LinkAnnotation | Región clickable que envía un PdfAction a través de Action() / Action(value) |
LinkAnnotation.Destination() / Destination(value) | Obtenga o establezca un destino de navegación explícito |
HighlightAnnotation | Marca un tramo de texto con un color de resaltado |
FreeTextAnnotation | Muestra una anotación de texto; configurada a través de Justification(), DefaultAppearanceObject(), Callout() |
CircleAnnotation | Dibuja una elipse dentro del rectángulo de la anotación |
WatermarkAnnotation | Anotación de superposición con un Opacity() / Opacity(value) accesor |
WidgetAnnotation | Anotación de apariencia de campo de formulario con ReadOnly(), Required(), Exportable(), DefaultAppearance() |
NamedAction | Acción de navegación predefinida (PredefinedAction enum) adjuntable a un LinkAnnotation |
JavascriptAction | Ejecuta una cadena ECMAScript mediante Script() / GetECMAScriptString() |
SubmitFormAction | Envía datos del formulario a una URL FileSpecification mediante Url() / Url(value) |
Border | Borde de anotación con Width(), Style() (BorderStyle), Effect() (BorderEffect) |
PdfAnnotationEditor | Fachada para la importación, modificación, aplanado y eliminación de anotaciones a nivel de documento |
PdfAnnotationEditor.FlatteningAnnotations() | Aplana las anotaciones en todo el documento vinculado |
PdfAnnotationEditor.DeleteAnnotations(annotType) | Elimina todas las anotaciones de un AnnotationType dado |
PdfAnnotationEditor.ImportAnnotationsFromXfdf(xfdfFile) | Importa anotaciones desde un archivo XFDF |