Cara Bekerja dengan Anotasi PDF di C++
Aspose.PDF FOSS untuk C++ merepresentasikan setiap anotasi PDF sebagai subclass dari kelas dasar umum Annotation, dan mengekspose anotasi pada halaman melalui AnnotationCollection yang dikembalikan oleh Page::Annotations(). Panduan ini menambahkan anotasi catatan teks biasa dan anotasi bergaya ke halaman dengan TextAnnotation, menyimpan dokumen, lalu membukanya kembali untuk membaca kembali anotasi dan menghapus satu. Perpustakaan diintegrasikan ke dalam proyek CMake sebagai dependensi subdirektori — tidak ada langkah instalasi paket-registry.
Panduan Langkah-demi-Langkah
Langkah 1: Instal Paket
Tambahkan perpustakaan sebagai subdirektori CMake dan tautkan target perpustakaan statis:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Verifikasi bahwa rantai alat dan langkah penautan terselesaikan dengan benar menggunakan program minimal:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Build yang berhasil yang mencetak pages: 0 mengonfirmasi bahwa perpustakaan telah ditautkan.
Langkah 2: Impor Kelas yang Diperlukan
#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;Langkah 3: Buat Dokumen dan Tambahkan Halaman
Buat dokumen baru dan tambahkan halaman ke dalamnya. PageCollection::Add() mengembalikan Page yang baru ditambahkan:
Document doc;
Page page = doc.Pages().Add();Langkah 4: Tambahkan Anotasi Teks ke Halaman
TextAnnotation ditampilkan sebagai komentar bergaya sticky-note. Bangun dari Document pemiliknya, atur posisinya dengan Rect() dan pesannya dengan Contents(), lalu tambahkan ke AnnotationCollection halaman:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Langkah 5: Gaya Anotasi Kedua dengan Warna, Garis Batas, dan Flag
Annotation juga mengekspos Color(), Border(), dan Flags(). Flags() mengambil bidang bit AnnotationFlags — gabungkan nilai dengan OR bitwise untuk mengatur lebih dari satu flag sekaligus:
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);Langkah 6: Simpan Dokumen
Tidak ada yang ditulis ke disk sampai Save() dijalankan:
doc.Save("annotated.pdf");Langkah 7: Buka kembali PDF dan Baca Anotasinya
Buka kembali file yang disimpan dan baca kembali AnnotationCollection pada halaman pertama. AnnotationCollection berbasis 0, dan Count() melaporkan berapa banyak anotasi yang dimiliki halaman tersebut:
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";
}
}Langkah 8: Hapus Anotasi dan Simpan Kembali
AnnotationCollection::Delete(index) menghapus anotasi berdasarkan posisinya yang berbasis 0. Hapus anotasi pertama dan simpan hasilnya ke file baru:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Masalah Umum dan Solusi
Tidak ada yang berubah pada PDF yang disimpan setelah memanggil Annotations().Add()
Dua hal biasanya salah di sini. Pertama, PageCollection bersifat 1-based (doc.Pages()[1] adalah halaman pertama) sementara AnnotationCollection bersifat 0-based (annots[0] adalah anotasi pertama) — mencampur dua skema pengindeksan tersebut menyebabkan operasi pada objek yang salah. Kedua, pastikan Document::Save() benar-benar dijalankan setelah anotasi ditambahkan; tidak ada yang ditulis ke disk sampai saat itu.
AnnotationCollection pengindeksan atau Delete(index) throws std::out_of_range
Indeks yang valid berkisar dari 0 hingga Count() - 1. Memberikan indeks negatif atau indeks yang sama dengan atau lebih besar dari Count() akan melempar std::out_of_range secara sengaja. Panggil Count() terlebih dahulu untuk membatasi setiap loop atau pencarian.
Remove() returns false pemanggilan kedua pada anotasi yang sama
Ini bukan kesalahan. Remove() melaporkan apakah anotasi ditemukan dan dihapus sebagai bool; memanggilnya lagi pada anotasi yang sudah tidak ada merupakan operasi nol yang mengembalikan false. Periksa nilai kembaliannya alih-alih mengasumsikan Remove() selalu berhasil.
Menetapkan yang baru AnnotationFlags nilai menghapus flag yang sudah saya setel
Flags(value) menggantikan seluruh set flag — tidak menggabungkan dengan nilai sebelumnya. Untuk menambahkan atau menghapus satu flag, baca flag saat ini terlebih dahulu dan gabungkan mereka dengan operator bitwise, misalnya a.Flags(a.Flags() | AnnotationFlags::Print) untuk menambahkan flag, atau a.Flags(a.Flags() & ~AnnotationFlags::Print) untuk menghapus satu flag sambil membiarkan yang lain tidak berubah.
Pertanyaan yang Sering Diajukan
Apa hubungan antara Annotation, TextAnnotation, dan subtipe anotasi lainnya?
Annotation adalah kelas dasar yang umum. TextAnnotation dan tipe anotasi konkret lainnya masing-masing mengkhususkannya untuk satu subtipe anotasi PDF, sambil berbagi accessor Rect(), Contents(), Color(), Flags(), dan Border() dari kelas dasar.
Apakah anotasi memiliki ruang lingkup pada seluruh dokumen atau hanya pada satu halaman?
Setiap halaman memiliki AnnotationCollection miliknya sendiri, yang dikembalikan oleh metode Annotations() halaman tersebut. Anotasi selalu memiliki ruang lingkup pada halaman tempat mereka ditambahkan, bukan pada seluruh dokumen.
Bagaimana cara menghitung berapa banyak anotasi pada sebuah halaman?
Panggil Count() pada AnnotationCollection yang dikembalikan oleh Page::Annotations().
Bisakah sebuah anotasi menjadi dapat dicetak dan hanya-baca sekaligus?
Ya. AnnotationFlags adalah bidang bit, jadi gabungkan nilai dengan OR bitwise, misalnya AnnotationFlags::Print | AnnotationFlags::ReadOnly.
Apakah menghapus anotasi dari AnnotationCollection menghapusnya dari file PDF di disk?
Hanya setelah Document::Save() dijalankan. Delete(), Remove(), dan Clear() hanya memodifikasi koleksi dalam memori — PDF di disk tidak berubah sampai dokumen disimpan.