Jak pracować z adnotacjami PDF w C++
Aspose.PDF FOSS for C++ reprezentuje każdą adnotację PDF jako podklasę wspólnej klasy bazowej Annotation, i udostępnia adnotacje na stronie poprzez AnnotationCollection zwracany przez Page::Annotations(). Ten przewodnik dodaje adnotację w postaci zwykłej notatki tekstowej oraz stylizowaną adnotację do strony przy użyciu TextAnnotation, zapisuje dokument, a następnie otwiera go ponownie, aby odczytać adnotacje i usunąć jedną z nich. Biblioteka jest zintegrowana z projektem CMake jako zależność podkatalogowa — nie ma kroku instalacji z rejestru pakietów.
Przewodnik krok po kroku
Krok 1: Zainstaluj pakiet
Dodaj bibliotekę jako podkatalog CMake i powiąż cel biblioteki statycznej:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Zweryfikuj, że łańcuch narzędziowy i krok linkowania rozwiązuje się poprawnie przy użyciu minimalnego programu:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Udany build, który wypisuje pages: 0, potwierdza, że biblioteka jest połączona.
Krok 2: Zaimportuj wymagane klasy
#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;Krok 3: Utwórz dokument i dodaj stronę
Utwórz nowy dokument i dodaj do niego stronę. PageCollection::Add() zwraca nowo dodany Page:
Document doc;
Page page = doc.Pages().Add();Krok 4: Dodaj adnotację tekstową do strony
TextAnnotation wyświetla się jako komentarz w stylu karteczki samoprzylepnej. Utwórz go z własnego Document, ustaw jego pozycję za pomocą Rect() i wiadomość za pomocą Contents(), a następnie dodaj go do AnnotationCollection strony:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Krok 5: Sformatuj drugą adnotację przy użyciu koloru, obramowania i flag
Annotation udostępnia również Color(), Border() i Flags(). Flags() przyjmuje pole bitowe AnnotationFlags — łącz wartości operatorem OR bitowym, aby jednocześnie ustawić więcej niż jedną flagę:
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);Krok 6: Zapisz dokument
Nic nie jest zapisywane na dysk, dopóki nie zostanie uruchomione Save():
doc.Save("annotated.pdf");Krok 7: Otwórz ponownie plik PDF i odczytaj jego adnotacje
Otwórz ponownie zapisany plik i odczytaj z powrotem AnnotationCollection pierwszej strony. AnnotationCollection jest indeksowane od 0, a Count() informuje, ile adnotacji znajduje się na stronie:
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";
}
}Krok 8: Usuń adnotację i zapisz ponownie
AnnotationCollection::Delete(index) usuwa adnotację według jej pozycji indeksowanej od 0. Usuń pierwszą adnotację i zapisz wynik do nowego pliku:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Typowe problemy i rozwiązania
Nic się nie zmienia w zapisanym pliku PDF po wywołaniu Annotations().Add()
Dwie rzeczy zazwyczaj idą tu nie tak. Po pierwsze, PageCollection jest indeksowane od 1 (doc.Pages()[1] to pierwsza strona), podczas gdy AnnotationCollection jest indeksowane od 0 (annots[0] to pierwsza adnotacja) — pomylenie dwóch schematów indeksacji prowadzi do operacji na niewłaściwym obiekcie. Po drugie, upewnij się, że Document::Save() faktycznie uruchamia się po dodaniu adnotacji; dopóki tak się nie stanie, nic nie jest zapisywane na dysk.
AnnotationCollection indeksowania lub Delete(index) throws std::out_of_range
Poprawne indeksy mieszczą się w przedziale od 0 do Count() - 1. Przekazanie ujemnego indeksu lub indeksu równego lub większego niż Count() zgłasza std::out_of_range zgodnie z projektem. Najpierw wywołaj Count(), aby ograniczyć dowolną pętlę lub wyszukiwanie.
Remove() returns false drugi raz, gdy wywołuję to na tej samej adnotacji
To nie jest błąd. Remove() informuje, czy adnotacja została znaleziona i usunięta jako bool; ponowne wywołanie na adnotacji, która już nie istnieje, jest operacją bez skutku i zwraca false. Sprawdź wartość zwracaną zamiast zakładać, że Remove() zawsze się powodzi.
Ustawienie nowego AnnotationFlags wartość usuwa flagi, które już ustawiłem
Flags(value) zastępuje cały zestaw flag — nie łączy się z poprzednią wartością. Aby dodać lub usunąć pojedynczą flagę, najpierw odczytaj bieżące flagi i połącz je przy użyciu operatorów bitowych, na przykład a.Flags(a.Flags() | AnnotationFlags::Print), aby dodać flagę, lub a.Flags(a.Flags() & ~AnnotationFlags::Print), aby usunąć jedną flagę, pozostawiając pozostałe niezmienione.
Najczęściej zadawane pytania
Jaki jest związek między Annotation, TextAnnotation a innymi podtypami adnotacji?
Annotation jest wspólną klasą bazową. TextAnnotation oraz inne konkretne typy adnotacji specjalizują ją dla jednego podtypu adnotacji PDF, jednocześnie dzieląc akcesory Rect(), Contents(), Color(), Flags() i Border() klasy bazowej.
Czy adnotacje dotyczą całego dokumentu, czy jednej strony?
Każda strona ma własny AnnotationCollection, zwracany przez metodę Annotations() tej strony. Adnotacje zawsze dotyczą strony, do której zostały dodane, a nie całego dokumentu.
Jak policzyć, ile adnotacji znajduje się na stronie?
Wywołaj Count() na AnnotationCollection zwróconym przez Page::Annotations().
Czy adnotacja może być jednocześnie drukowalna i tylko do odczytu?
Tak. AnnotationFlags jest polem bitowym, więc łącz wartości operatorem OR bitowym, na przykład AnnotationFlags::Print | AnnotationFlags::ReadOnly.
Czy usunięcie adnotacji z AnnotationCollection usuwa ją z pliku PDF na dysku?
Tylko po uruchomieniu Document::Save(). Delete(), Remove() i Clear() modyfikują jedynie kolekcję w pamięci — PDF na dysku pozostaje niezmieniony, dopóki dokument nie zostanie zapisany.