Come lavorare con le annotazioni PDF in C++
Aspose.PDF FOSS per C++ rappresenta ogni annotazione PDF come una sottoclasse della classe base comune Annotation, e espone le annotazioni su una pagina tramite il AnnotationCollection restituito da Page::Annotations(). Questa guida aggiunge un’annotazione di nota di testo semplice e un’annotazione stilizzata a una pagina con TextAnnotation, salva il documento, poi lo riapre per leggere le annotazioni e rimuoverne una. La libreria è integrata in un progetto CMake come dipendenza di sottodirectory — non è necessario un passaggio di installazione dal registro dei pacchetti.
Guida passo-passo
Passo 1: Installa il pacchetto
Aggiungi la libreria come sottodirectory CMake e collega il target della libreria statica:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Verifica che la toolchain e il passaggio di linking si risolvano correttamente con un programma minimale:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Una compilazione riuscita che stampa pages: 0 conferma che la libreria è collegata.
Passo 2: Importa le classi richieste
#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;Passo 3: Crea un documento e aggiungi una pagina
Crea un nuovo documento e aggiungi una pagina. PageCollection::Add() restituisce il Page appena aggiunto:
Document doc;
Page page = doc.Pages().Add();Passo 4: Aggiungi un’annotazione di testo alla pagina
TextAnnotation viene visualizzato come un commento in stile sticky-note. Costruiscilo dall’Document proprietario, imposta la sua posizione con Rect() e il suo messaggio con Contents(), quindi aggiungilo al AnnotationCollection della pagina:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Passo 5: Stila una seconda annotazione con colore, bordo e flag
Annotation espone anche Color(), Border() e Flags(). Flags() accetta un campo a bit AnnotationFlags — combina i valori con l’OR bitwise per impostare più di un flag alla volta:
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);Passo 6: Salva il documento
Niente viene scritto su disco finché non viene eseguito Save():
doc.Save("annotated.pdf");Passo 7: Riapri il PDF e leggi le sue annotazioni
Riapri il file salvato e leggi indietro il AnnotationCollection della sua prima pagina. AnnotationCollection è basato su zero, e Count() indica quante annotazioni contiene la pagina:
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";
}
}Passo 8: Rimuovi un’annotazione e salva nuovamente
AnnotationCollection::Delete(index) rimuove un’annotazione in base alla sua posizione basata su zero. Elimina la prima annotazione e salva il risultato in un nuovo file:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Problemi comuni e soluzioni
Niente cambia nel PDF salvato dopo la chiamata Annotations().Add()
Due cose vanno spesso storte qui. Prima, PageCollection è basato su 1 (doc.Pages()[1] è la prima pagina) mentre AnnotationCollection è basato su 0 (annots[0] è la prima annotazione) — confondere i due schemi di indicizzazione porta a operare sull’oggetto sbagliato. Secondo, verifica che Document::Save() venga realmente eseguito dopo che l’annotazione è stata aggiunta; nulla viene scritto su disco fino a quel momento.
AnnotationCollection indicizzazione o Delete(index) throws std::out_of_range
Gli indici validi vanno da 0 a Count() - 1. Passare un indice negativo o un indice uguale o superiore a Count() genera std::out_of_range per design. Chiama Count() prima per limitare qualsiasi ciclo o ricerca.
Remove() returns false la seconda volta che lo chiamo sulla stessa annotazione
Questo non è un errore. Remove() segnala se l’annotazione è stata trovata e rimossa come bool; chiamarlo di nuovo su un’annotazione già rimossa è un’operazione nulla che restituisce false. Controlla il valore di ritorno invece di presumere che Remove() abbia sempre successo.
Impostare un nuovo AnnotationFlags valore cancella i flag che avevo già impostato
Flags(value) sostituisce l’intero set di flag — non si fonde con il valore precedente. Per aggiungere o rimuovere un singolo flag, leggi prima i flag attuali e combinali con operatori bitwise, per esempio a.Flags(a.Flags() | AnnotationFlags::Print) per aggiungere un flag, o a.Flags(a.Flags() & ~AnnotationFlags::Print) per rimuovere un flag lasciando intatti gli altri.
Domande Frequenti
Qual è la relazione tra Annotation, TextAnnotation e gli altri sotto-tipi di annotazione?
Annotation è la classe base comune. TextAnnotation e gli altri tipi concreti di annotazione specializzano ciascuno per un sotto-tipo di annotazione PDF, condividendo gli accessor Rect(), Contents(), Color(), Flags() e Border() della classe base.
Le annotazioni sono limitate all’intero documento o a una singola pagina?
Ogni pagina ha il proprio AnnotationCollection, restituito dal metodo Annotations() di quella pagina. Le annotazioni sono sempre limitate alla pagina a cui sono state aggiunte, non all’intero documento.
Come faccio a contare quante annotazioni ci sono su una pagina?
Chiama Count() sul AnnotationCollection restituito da Page::Annotations().
Un’annotazione può essere sia stampabile che di sola lettura allo stesso tempo?
Sì. AnnotationFlags è un campo a bit, quindi combina i valori con l’OR bitwise, ad esempio AnnotationFlags::Print | AnnotationFlags::ReadOnly.
L’eliminazione di un’annotazione da AnnotationCollection la rimuove dal file PDF sul disco?
Solo dopo che Document::Save() viene eseguito. Delete(), Remove() e Clear() modificano solo la collezione in memoria — il PDF sul disco rimane invariato finché il documento non viene salvato.