Come lavorare con le annotazioni PDF in C++

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.

Vedi anche

 Italiano