Comment travailler avec les annotations PDF en C++
Aspose.PDF FOSS for C++ représente chaque annotation PDF comme une sous-classe de la classe de base commune Annotation, et expose les annotations sur une page via le AnnotationCollection renvoyé par Page::Annotations(). Ce guide ajoute une annotation de note texte simple et une annotation stylisée à une page avec TextAnnotation, enregistre le document, puis le rouvre pour lire les annotations et en supprimer une. La bibliothèque est intégrée dans un projet CMake en tant que dépendance de sous-répertoire — il n’y a aucune étape d’installation via un registre de paquets.
Guide étape par étape
Étape 1: Installer le paquet
Ajoutez la bibliothèque en tant que sous-répertoire CMake et liez la cible de bibliothèque statique:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Vérifiez que la chaîne d’outils et l’étape de liaison se résolvent correctement avec un programme minimal:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Une construction réussie qui affiche pages: 0 confirme que la bibliothèque est liée.
Étape 2 : Importer les classes requises
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/rectangle.hpp>
#include <aspose/pdf/color.hpp>
#include <aspose/pdf/annotations/annotation.hpp>
#include <aspose/pdf/annotations/annotation_collection.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>
#include <aspose/pdf/annotations/annotation_flags.hpp>
#include <aspose/pdf/annotations/border.hpp>
#include <aspose/pdf/annotations/border_style.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;Étape 3 : Créer un document et ajouter une page
Créez un nouveau document et ajoutez-y une page. PageCollection::Add() renvoie le Page nouvellement ajouté :
Document doc;
Page page = doc.Pages().Add();Étape 4 : Ajouter une annotation de texte à la page
TextAnnotation s’affiche comme un commentaire de type note autocollante. Construisez-le à partir du Document propriétaire, définissez sa position avec Rect() et son message avec Contents(), puis ajoutez-le au AnnotationCollection de la page :
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Étape 5 : Styliser une deuxième annotation avec une couleur, une bordure et des indicateurs
Annotation expose également Color(), Border() et Flags(). Flags() prend un champ de bits AnnotationFlags — combinez les valeurs avec l’opérateur OU binaire pour définir plusieurs indicateurs à la fois :
TextAnnotation flagged{doc};
flagged.Rect(Rectangle(100.0, 600.0, 300.0, 650.0, false));
flagged.Contents("Needs follow-up");
flagged.Color(Color::FromRgb(220, 20, 20));
flagged.Flags(AnnotationFlags::Print | AnnotationFlags::ReadOnly);
flagged.Border().Width(2);
flagged.Border().Style(BorderStyle::Dashed);
page.Annotations().Add(flagged);Étape 6 : Enregistrer le document
Rien n’est écrit sur le disque tant que Save() ne s’exécute pas:
doc.Save("annotated.pdf");Étape 7: Réouvrir le PDF et lire ses annotations
Rouvrir le fichier enregistré et lire à nouveau le AnnotationCollection de la première page. AnnotationCollection est indexé à partir de 0, et Count() indique le nombre d’annotations que la page contient:
Document reopened("annotated.pdf");
auto& annots = reopened.Pages()[1].Annotations();
std::cout << "Annotation count: " << annots.Count() << "\n";
for (int i = 0; i < annots.Count(); ++i) {
const auto& a = annots[i];
if (a.AnnotationType() == AnnotationType::Text) {
std::cout << "Text annotation: " << a.Contents() << "\n";
}
}Étape 8: Supprimer une annotation et réenregistrer
AnnotationCollection::Delete(index) supprime une annotation selon sa position indexée à partir de 0. Supprimez la première annotation et enregistrez le résultat dans un nouveau fichier:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Problèmes courants et solutions
Rien ne change dans le PDF enregistré après l’appel Annotations().Add()
Deux choses posent souvent problème ici. Premièrement, PageCollection est basé à 1 (doc.Pages()[1] est la première page) tandis que AnnotationCollection est basé à 0 (annots[0] est la première annotation) — confondre les deux schémas d’indexation conduit à agir sur le mauvais objet. Deuxièmement, assurez-vous que Document::Save() s’exécute réellement après l’ajout de l’annotation ; rien n’est écrit sur le disque avant cela.
AnnotationCollection indexation ou Delete(index) throws std::out_of_range
Les indices valides vont de 0 à Count() - 1. Fournir un indice négatif ou un indice égal ou supérieur à Count() lance std::out_of_range par conception. Appelez Count() d’abord pour délimiter toute boucle ou recherche.
Remove() returns false la deuxième fois que je l’appelle sur la même annotation
Ce n’est pas une erreur. Remove() indique si l’annotation a été trouvée et supprimée en tant que bool; l’appeler à nouveau sur une annotation déjà disparue ne fait rien et renvoie false. Vérifiez la valeur de retour au lieu de supposer que Remove() réussit toujours.
Définir une nouvelle AnnotationFlags valeur efface les flags que j’avais déjà définis
Flags(value) remplace l’ensemble complet de drapeaux — il ne fusionne pas avec la valeur précédente. Pour ajouter ou supprimer un drapeau unique, lisez d’abord les drapeaux actuels et combinez-les avec des opérateurs binaires, par exemple a.Flags(a.Flags() | AnnotationFlags::Print) pour ajouter un drapeau, ou a.Flags(a.Flags() & ~AnnotationFlags::Print) pour en supprimer un tout en laissant les autres intacts.
Foire aux questions
Quelle est la relation entre Annotation, TextAnnotation et les autres sous-types d’annotation?
Annotation est la classe de base commune. TextAnnotation et les autres types d’annotation concrets la spécialisent chacun pour un sous-type d’annotation PDF, tout en partageant les accesseurs Rect(), Contents(), Color(), Flags() et Border() de la classe de base.
Les annotations sont-elles limitées à l’ensemble du document ou à une seule page?
Chaque page possède son propre AnnotationCollection, renvoyé par la méthode Annotations() de cette page. Les annotations sont toujours limitées à la page à laquelle elles ont été ajoutées, et non au document dans son ensemble.
Comment puis-je compter le nombre d’annotations présentes sur une page?
Appelez Count() sur le AnnotationCollection renvoyé par Page::Annotations().
Une annotation peut-elle être à la fois imprimable et en lecture seule simultanément?
Oui. AnnotationFlags est un champ de bits, il faut donc combiner les valeurs avec un OU binaire, par exemple AnnotationFlags::Print | AnnotationFlags::ReadOnly.
La suppression d’une annotation de AnnotationCollection la supprime-t-elle du fichier PDF sur le disque?
Uniquement après l’exécution de Document::Save(). Delete(), Remove() et Clear() ne modifient que la collection en mémoire — le PDF sur le disque reste inchangé jusqu’à ce que le document soit enregistré.