Wie man mit PDF-Anmerkungen in C++ arbeitet
Aspose.PDF FOSS für C++ stellt jede PDF-Annotation als Unterklasse der gemeinsamen Annotation Basisklasse dar und stellt die Annotationen auf einer Seite über das AnnotationCollection bereit, das von Page::Annotations() zurückgegeben wird. Dieser Leitfaden fügt einer Seite mit TextAnnotation eine einfache Textnotiz-Annotation und eine formatierte Annotation hinzu, speichert das Dokument, öffnet es dann erneut, um die Annotationen auszulesen und eine zu entfernen. Die Bibliothek ist in ein CMake-Projekt als Unterverzeichnis-Abhängigkeit integriert – es gibt keinen Installationsschritt über ein Paket-Register.
Schritt-für-Schritt-Anleitung
Schritt 1: Paket installieren
Fügen Sie die Bibliothek als CMake-Unterverzeichnis hinzu und verlinken Sie das statische Bibliotheksziel:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Überprüfen Sie, ob die Toolchain und der Linkschritt mit einem Minimalprogramm korrekt aufgelöst werden:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Ein erfolgreicher Build, der pages: 0 ausgibt, bestätigt, dass die Bibliothek verlinkt ist.
Schritt 2: Erforderliche Klassen importieren
#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;Schritt 3: Ein Dokument erstellen und eine Seite hinzufügen
Erstelle ein neues Dokument und füge ihm eine Seite hinzu. PageCollection::Add() gibt das neu hinzugefügte Page zurück:
Document doc;
Page page = doc.Pages().Add();Schritt 4: Eine Textanmerkung zur Seite hinzufügen
TextAnnotation wird als ein Kommentar im Stil einer Haftnotiz dargestellt. Erstelle ihn aus dem zugehörigen Document, setze seine Position mit Rect() und seine Nachricht mit Contents(), und füge ihn dann zu dem AnnotationCollection der Seite hinzu:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Schritt 5: Eine zweite Anmerkung mit Farbe, einem Rahmen und Flags formatieren
Annotation stellt außerdem Color(), Border() und Flags() bereit. Flags() akzeptiert ein AnnotationFlags-Bitfeld — kombiniere Werte mit bitweisem ODER, um mehr als ein Flag gleichzeitig zu setzen:
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);Schritt 6: Das Dokument speichern
Bis Save() ausgeführt wird, wird nichts auf die Festplatte geschrieben:
doc.Save("annotated.pdf");Schritt 7: PDF erneut öffnen und seine Anmerkungen lesen
Öffnen Sie die gespeicherte Datei erneut und lesen Sie das AnnotationCollection der ersten Seite zurück. AnnotationCollection ist nullbasiert, und Count() gibt an, wie viele Anmerkungen die Seite enthält:
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";
}
}Schritt 8: Eine Anmerkung entfernen und erneut speichern
AnnotationCollection::Delete(index) entfernt eine Anmerkung anhand ihrer nullbasierten Position. Löschen Sie die erste Anmerkung und speichern Sie das Ergebnis in einer neuen Datei:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Häufige Probleme und Lösungen
Nichts ändert sich in der gespeicherten PDF nach dem Aufruf Annotations().Add()
Zwei Dinge gehen hier häufig schief. Erstens ist PageCollection 1-basiert (doc.Pages()[1] ist die erste Seite), während AnnotationCollection 0-basiert ist (annots[0] ist die erste Annotation) — das Verwechseln der beiden Indexierungsschemata führt dazu, dass das falsche Objekt bearbeitet wird. Zweitens stellen Sie sicher, dass Document::Save() tatsächlich nach dem Hinzufügen der Annotation ausgeführt wird; bis dahin wird nichts auf die Festplatte geschrieben.
AnnotationCollection Indizierung oder Delete(index) throws std::out_of_range
Gültige Indizes liegen zwischen 0 und Count() - 1. Das Übergeben eines negativen Index oder eines Index, der gleich Count() ist oder größer ist, löst aus Design std::out_of_range aus. Rufen Sie zuerst Count() auf, um jede Schleife oder Suche zu begrenzen.
Remove() returns false das zweite Mal, wenn ich sie bei derselben Annotation aufrufe
Dies ist kein Fehler. Remove() meldet, ob die Annotation als bool gefunden und entfernt wurde; sie erneut für eine bereits gelöschte Annotation aufzurufen, hat keine Wirkung und gibt false zurück. Prüfen Sie den Rückgabewert, anstatt anzunehmen, dass Remove() immer erfolgreich ist.
Festlegen eines neuen AnnotationFlags Wert löscht Flags, die ich bereits gesetzt hatte
Flags(value) ersetzt das gesamte Flag-Set — es wird nicht mit dem vorherigen Wert zusammengeführt. Um ein einzelnes Flag hinzuzufügen oder zu entfernen, lesen Sie zunächst die aktuellen Flags und kombinieren Sie sie mit bitweisen Operatoren, zum Beispiel a.Flags(a.Flags() | AnnotationFlags::Print), um ein Flag hinzuzufügen, oder a.Flags(a.Flags() & ~AnnotationFlags::Print), um ein Flag zu entfernen, während die übrigen unverändert bleiben.
Häufig gestellte Fragen
Wie ist die Beziehung zwischen Annotation, TextAnnotation und den anderen Annotation-Subtypen?
Annotation ist die gemeinsame Basisklasse. TextAnnotation und die anderen konkreten Annotationstypen spezialisieren sie jeweils für einen PDF-Annotation-Subtype, während sie die Rect(), Contents(), Color(), Flags() und Border() Accessor-Methoden teilen.
Sind Annotationen auf das gesamte Dokument oder auf eine einzelne Seite begrenzt?
Jede Seite hat ihr eigenes AnnotationCollection, das von der Annotations()-Methode dieser Seite zurückgegeben wird. Annotationen sind immer auf die Seite beschränkt, zu der sie hinzugefügt wurden, nicht auf das gesamte Dokument.
Wie kann ich zählen, wie viele Annotationen sich auf einer Seite befinden?
Rufen Sie Count() auf dem AnnotationCollection auf, das von Page::Annotations() zurückgegeben wird.
Kann eine Annotation gleichzeitig druckbar und schreibgeschützt sein?
Ja. AnnotationFlags ist ein Bitfeld, daher kombinieren Sie Werte mit bitweisem ODER, zum Beispiel AnnotationFlags::Print | AnnotationFlags::ReadOnly.
Entfernt das Löschen einer Anmerkung aus AnnotationCollection die Anmerkung aus der PDF-Datei auf der Festplatte?
Erst nachdem Document::Save() ausgeführt wurde. Delete(), Remove() und Clear() ändern nur die In-Memory-Sammlung — die PDF auf der Festplatte bleibt unverändert, bis das Dokument gespeichert wird.