Travailler avec les annotations PDF
Travailler avec les annotations PDF
Les annotations PDF dans Aspose.PDF FOSS pour C++ sont représentées par la classe de base Annotation et ses sous-types concrets (TextAnnotation, LinkAnnotation, HighlightAnnotation, FreeTextAnnotation, CircleAnnotation, WatermarkAnnotation, WidgetAnnotation et d’autres). Chaque page expose ses annotations via Page.Annotations(), qui renvoie un AnnotationCollection. Ce guide couvre l’ajout d’annotations à une page, leur itération et suppression, la lecture des annotations d’un document existant, l’attachement d’actions de lien, la personnalisation de l’apparence et l’aplatissement des annotations.
Ajout d’annotations à une page
Créez une instance d’annotation concrète, positionnez-la avec un Rectangle, et ajoutez-la à la collection de la page avec AnnotationCollection.Add(). TextAnnotation représente un commentaire de type note autocollante ancré à un point sur la page :
#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) obtiennent et définissent le texte de la note, et Annotation.Rect() / Rect(value) positionnent l’annotation sur la page.
Itération et suppression des annotations
AnnotationCollection prend en charge le comptage, l’accès indexé, les vérifications d’appartenance et la suppression par valeur ou par indice:
#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) et Remove(annotation) fonctionnent sur une référence d’annotation spécifique; Delete(index) supprime par position, et Delete(annotation) supprime une annotation précise sans nécessiter son indice. IsReadOnly() indique si la collection peut être modifiée.
Lecture des annotations d’un document existant
Lorsqu’un document est chargé, ses annotations sont déjà renseignées et peuvent être inspectées sans ajouter quoi que ce soit. Annotation.AnnotationType() indique le sous-type (AnnotationType::Text, AnnotationType::Highlight, AnnotationType::Link, AnnotationType::FreeText, AnnotationType::FileAttachment, AnnotationType::Watermark, et autres):
#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";
}
}
}L’ordre des annotations et le sous-type sont conservés lors d’un aller-retour sauvegarde/rechargement, de sorte que le code qui indexe Annotations() après le chargement d’un document voit la même séquence que celle présente lors de l’écriture du fichier.
Annotations de lien et actions
LinkAnnotation attache une région cliquable à une page et déclenche un PdfAction lorsqu’il est activé. NamedAction se rend vers une cible de navigation prédéfinie, JavascriptAction exécute une chaîne ECMAScript, et SubmitFormAction envoie les données du formulaire à une URL via 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) accepte n’importe quel sous-type PdfAction et le clone en interne, de sorte que l’annotation conserve sa propre copie de l’action. LinkAnnotation.Destination() / Destination(value) définissent une cible de navigation explicite au lieu d’une action, et Highlighting() / Highlighting(value) contrôlent le retour visuel affiché pendant le clic sur le lien.
Apparence de l’annotation: bordure, drapeaux et couleur
Chaque Annotation expose un Border, un champ de bits de AnnotationFlags, et un Color utilisé pour rendre son apparence:
#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() accepte BorderStyle::Solid, Dashed, Beveled, Inset ou Underline. Border.Effect() prend également en charge un contour BorderEffect::Cloudy avec EffectIntensity() contrôlant à quel point il est prononcé. AnnotationFlags est un champ de bits — combinez des valeurs telles que Print, NoZoom, ReadOnly et LockedContents pour contrôler le comportement d’une annotation dans un visualiseur sans en modifier le contenu visible.
Aplatir les annotations
Une annotation unique peut être aplatie — fusionnée au contenu de la page et rendue non interactive — en appelant Annotation.Flatten() directement:
#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");
}Pour les opérations d’annotation à l’échelle du document, PdfAnnotationEditor suit le modèle partagé Facade utilisé à travers le API: liez un document source avec BindPdf(), appliquez une ou plusieurs opérations d’annotation, puis écrivez le résultat avec 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() supprime toutes les annotations du document lié; DeleteAnnotations(annotType) limite la suppression à une seule AnnotationType. ImportAnnotationsFromXfdf(xfdfFile) et ImportAnnotationsFromFdf(fdfFile) chargent les données d’annotation exportées depuis un autre visualiseur PDF.
Conseils et meilleures pratiques
- Ajoutez toujours une annotation nouvellement construite à
Page.Annotations()avant d’appelerDocument.Save()— une annotation qui n’est jamais ajoutée à une collection n’est pas écrite dans le fichier de sortie. - Utilisez
AnnotationCollection.Contains(annotation)avant d’appelerRemove()si vous n’êtes pas certain que l’annotation soit toujours présente;Remove()renvoiefalseau lieu de lever une exception lorsque l’annotation est absente. - Vérifiez
Annotation.AnnotationType()avant de faire un cast ou de bifurquer selon le comportement du sous-type lors de l’itération des annotations chargées depuis un fichier PDF non fiable ou tiers. - Aplatissez les annotations avec
Annotation.Flatten()(ouPdfAnnotationEditor.FlatteningAnnotations()pour l’ensemble du document) avant d’archiver un document afin que les examinateurs utilisant d’autres outils voient la même apparence que vous avez créée. AnnotationFlagsest un champ de bits — combinez les drapeaux avec les valeurs entières sous-jacentes de l’énumération plutôt que de supposer qu’un seul drapeau peut être actif à la fois.
Problèmes courants
| Problème | Cause | Correction |
|---|---|---|
| Annotation non visible après l’enregistrement | L’annotation a été construite mais n’a jamais été ajoutée à Page.Annotations() | Appelez page.Annotations().Add(annotation) avant doc.Save() |
Remove() renvoie false | La référence d’annotation transmise ne correspond à aucune entrée actuellement dans la collection | Utilisez Contains() d’abord, ou supprimez par indice avec Delete(index) |
| Type d’annotation incorrect après rechargement | Le code supposait un sous-type spécifique sans vérifier AnnotationType() | Effectuez une branche sur Annotation.AnnotationType() avant de traiter l’objet comme un sous-type spécifique |
| L’action du lien semble non définie après l’affectation | Une variable locale PdfAction est sortie de la portée ; LinkAnnotation.Action() renvoie la copie clonée de l’annotation, pas l’objet original | Lisez l’action via link.Action() plutôt que de conserver la variable locale originale |
L’opération PdfAnnotationEditor n’a aucun effet | BindPdf() n’a pas été appelé, ou a été appelé avec un chemin qui n’existe pas | Vérifiez que BindPdf() réussit avant d’appeler FlatteningAnnotations() ou DeleteAnnotations() |
FAQ
Comment ajouter une annotation de type commentaire à une page PDF?
Construisez un TextAnnotation avec la cible Document, définissez son Rect() et son Contents(), puis ajoutez-le à page.Annotations() avant d’enregistrer.
Comment puis-je savoir quel type d’annotation je regarde?
Appelez Annotation.AnnotationType(), qui renvoie une valeur d’énumération AnnotationType telle que Text, Link, Highlight, FreeText, FileAttachment ou Watermark.
Une annotation peut-elle contenir plusieurs drapeaux?
Oui. AnnotationFlags est un champ de bits (Default, Invisible, Hidden, Print, NoZoom, ReadOnly, LockedContents, et d’autres), de sorte que plusieurs drapeaux peuvent être combinés sur une même annotation.
Quelle est la différence entre aplatir une annotation et aplatir un document?
Annotation.Flatten() fusionne une annotation unique dans le contenu de sa page. PdfAnnotationEditor.FlatteningAnnotations() (éventuellement limité par une plage de pages et AnnotationType via la surcharge qui accepte start, end et annotType) aplatit l’ensemble du document lié en un seul appel.
Comment supprimer toutes les annotations d’un type donné d’un document?
Liez le document avec PdfAnnotationEditor.BindPdf(), appelez DeleteAnnotations(annotType) avec la cible AnnotationType, puis Save() le résultat.
API Reference Résumé
| Classe/Méthode | Description |
|---|---|
Annotation | Classe de base abstraite pour tous les sous-types d’annotation PDF |
Annotation.Rect() / Rect(value) | Obtient ou définit le rectangle englobant de l’annotation |
Annotation.Contents() / Contents(value) | Obtenir ou définir le contenu texte de l’annotation |
Annotation.AnnotationType() | Renvoie la valeur d’énumération AnnotationType pour cette annotation |
Annotation.Flags() / Flags(value) | Obtenir ou définir le champ de bits AnnotationFlags |
Annotation.Border() / Border(value) | Obtient ou définit le Border de l’annotation |
Annotation.Color() / Color(value) | Obtenir ou définir l’affichage de l’annotation Color |
Annotation.Flatten() | Fusionne cette annotation dans le contenu de la page, la rendant non-interactive |
AnnotationCollection | Collection ordonnée d’annotations sur une page, renvoyée par Page.Annotations() |
AnnotationCollection.Add(annotation) / Add(annotation, considerRotation) | Ajoute une annotation à la collection |
AnnotationCollection.Count() | Renvoie le nombre d’annotations dans la collection |
AnnotationCollection.Contains(annotation) | Indique si la collection contient l’annotation donnée |
AnnotationCollection.Remove(annotation) | Supprime une annotation spécifique ; renvoie false si elle n’est pas trouvée |
AnnotationCollection.Delete(index) / Delete(annotation) | Supprime une annotation par indice ou par référence |
AnnotationCollection.Clear() | Supprime toutes les annotations de la collection |
TextAnnotation | Annotation de style post-it avec Open() et Icon() (TextIcon) |
LinkAnnotation | Région cliquable déclenchant un PdfAction via Action() / Action(value) |
LinkAnnotation.Destination() / Destination(value) | Obtient ou définit une cible de navigation explicite |
HighlightAnnotation | Marque une portion de texte avec une couleur de surbrillance |
FreeTextAnnotation | Affiche un texte d’appel ; configuré via Justification(), DefaultAppearanceObject(), Callout() |
CircleAnnotation | Dessine une ellipse à l’intérieur du rectangle de l’annotation |
WatermarkAnnotation | Annotation de superposition avec un accesseur Opacity() / Opacity(value) |
WidgetAnnotation | Annotation d’apparence du champ de formulaire avec ReadOnly(), Required(), Exportable(), DefaultAppearance() |
NamedAction | Action de navigation prédéfinie (PredefinedAction enum) attachable à un LinkAnnotation |
JavascriptAction | Exécute une chaîne ECMAScript via Script() / GetECMAScriptString() |
SubmitFormAction | Envoie les données du formulaire à une URL FileSpecification via Url() / Url(value) |
Border | Bordure d’annotation avec Width(), Style() (BorderStyle), Effect() (BorderEffect) |
PdfAnnotationEditor | Facade pour l’importation, la modification, l’aplatissement et la suppression d’annotations à l’échelle du document |
PdfAnnotationEditor.FlatteningAnnotations() | Aplatisse les annotations à travers le document lié |
PdfAnnotationEditor.DeleteAnnotations(annotType) | Supprime toutes les annotations d’un AnnotationType donné |
PdfAnnotationEditor.ImportAnnotationsFromXfdf(xfdfFile) | Importe les annotations d’un fichier XFDF |