Cara Bekerja dengan Anotasi PDF di Python
Aspose.PDF FOSS untuk Python menampilkan setiap anotasi pada halaman sebagai objek Annotation yang hidup melalui AnnotationCollection halaman, sehingga Anda dapat menambahkan anotasi markup, tautan, dan 3D, memeriksa properti khusus tipe mereka, dan menghasilkan aliran tampilan yang dibutuhkan penampil PDF untuk merendernya — semuanya dari Python murni. Panduan ini menunjukkan cara menginstal pustaka, menambahkan anotasi, membacanya kembali, dan menghasilkan aliran tampilan mereka.
Panduan Langkah-demi-Langkah
Langkah 1: Instal Paket
Instal paket Aspose.PDF FOSS:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .Verifikasi instalasi dengan mengimpor modul aspose_pdf tingkat atas, yang menampilkan kelas Document yang digunakan dalam langkah-langkah di bawah ini. Potongan kode mencetak aspose_pdf OK ketika impor berhasil; sebuah ModuleNotFoundError biasanya berarti paket dipasang ke lingkungan Python yang berbeda dari yang menjalankan skrip Anda:
import aspose_pdf
print("aspose_pdf OK")Langkah 2: Impor Kelas yang Diperlukan
Impor Document untuk menampung PDF, plus kelas anotasi yang akan Anda gunakan untuk membuat dan memeriksa anotasi:
from aspose_pdf import Document
from aspose_pdf.annotations import (
Annotation,
AnnotationType,
AnnotationFlags,
MarkupAnnotation,
LinkAnnotation,
)Langkah 3: Tambahkan Anotasi ke Halaman
Setiap Page mengekspos anotasinya melalui properti annotations, sebuah AnnotationCollection. Panggil add(subtype, rect, contents) dengan nama subtipe, sebuah persegi (left, bottom, right, top), dan konten teks anotasi. Subtipe markup standar seperti "Highlight" dikembalikan sebagai instance MarkupAnnotation:
from aspose_pdf import Document
document = Document()
document.pages.add()
page = document.pages[0]
annotation = page.annotations.add(
"Highlight",
(100, 700, 300, 720),
"Key clause",
)
print(type(annotation).__name__) # MarkupAnnotation
print(annotation.contents) # Key clauseLangkah 4: Buat Anotasi dari Subtipe Enum
AnnotationType mengenumerasi setiap subtipe anotasi PDF standar (PDF 32000-1:2008, Tabel 169), sehingga Anda dapat mengirimkan anggota enum alih-alih string mentah. Data spesifik tipe — seperti titik sudut poligon — masuk ke dalam kamus properties dan dibaca kembali dengan get_property:
from aspose_pdf import Document
from aspose_pdf.annotations import AnnotationType
document = Document()
document.pages.add()
page = document.pages[0]
annotation = page.annotations.add(
AnnotationType.POLYGON,
(0, 0, 10, 10),
"",
properties={"Vertices": [0, 0, 10, 0, 5, 10]},
)
print(annotation.subtype) # Polygon
print(annotation.get_property("Vertices")) # [0, 0, 10, 0, 5, 10]Langkah 5: Baca dan Iterasi Anotasi yang Ada
AnnotationCollection dapat diiterasi, sehingga Anda dapat menelusuri setiap anotasi yang sudah ada di halaman — termasuk yang dimuat dari PDF yang ada — dan membaca properti umum yang setiap Annotation ekspos (subtype, contents, rect, title, author, color):
from aspose_pdf import Document
document = Document()
document.pages.add()
page = document.pages[0]
page.annotations.add("Text", (50, 50, 70, 70), "First note")
page.annotations.add("Text", (80, 80, 100, 100), "Second note")
for annotation in page.annotations:
print(annotation.subtype, "-", annotation.contents)Langkah 6: Hasilkan Stream Penampilan Anotasi
Sebuah anotasi yang dibuat tanpa appearance_normal eksplisit tidak memiliki rendering yang terlihat (/AP /N) sampai satu dihasilkan. Panggil generate_appearance(force) pada satu Annotation, atau generate_appearances(force) pada seluruh AnnotationCollection untuk menyintesis setiap stream penampilan yang hilang pada halaman sekaligus:
from aspose_pdf import Document
from aspose_pdf.engine.cos import AnnotationName
document = Document()
document.pages.add()
page = document.pages[0]
stamp = page.annotations.add(
"Stamp",
(100, 100, 260, 150),
"",
properties={"Name": AnnotationName("Approved")},
)
if stamp.generate_appearance():
print(f"Appearance stream: {len(stamp.appearance_normal)} byte(s)")
# Regenerate every missing appearance stream on the page in one call:
count = page.annotations.generate_appearances(force=True)
print(f"Regenerated {count} appearance stream(s)")Langkah 7: Bedakan Subkelas Anotasi
AnnotationCollection.add() mengirim ke subkelas tertentu berdasarkan subtipe: subtipe bergaya markup (Highlight, Square, Stamp, dan serupa) kembali sebagai MarkupAnnotation, dan "Link" kembali sebagai LinkAnnotation. Keduanya mewarisi setiap metode dan properti dari Annotation, sehingga pemeriksaan isinstance memungkinkan Anda bercabang berdasarkan jenis anotasi tanpa memeriksa string subtype secara langsung:
from aspose_pdf import Document
from aspose_pdf.annotations import LinkAnnotation, MarkupAnnotation
document = Document()
document.pages.add()
page = document.pages[0]
link = page.annotations.add("Link", (50, 750, 200, 770), "")
highlight = page.annotations.add("Highlight", (50, 700, 200, 720), "")
print(isinstance(link, LinkAnnotation)) # True
print(isinstance(highlight, MarkupAnnotation)) # TrueMasalah Umum dan Solusi
get_property returns None untuk properti yang baru saja saya setel
properties kunci adalah nama bidang PDF yang tepat, sensitif huruf besar/kecil ("Vertices", "Name", dan serupa) — kesalahan ketik atau huruf yang salah diabaikan secara diam-diam alih-alih memunculkan error. Berikan argumen default ke get_property(name, default) dan periksa secara eksplisit saat men-debug subtipe baru.
generate_appearance() returns False
Tidak setiap kombinasi subtipe dan properti dapat disintesis menjadi aliran tampilan oleh generator bawaan. Periksa has_appearance sebelum mengasumsikan panggilan berhasil, dan sediakan appearance_normal (bytes) yang telah dipra-render langsung pada add() untuk subtipe yang tidak didukung oleh generator.
Subclass anotasi yang tidak terduga setelah add()
String subtipe (atau anggota AnnotationType) yang Anda berikan menentukan kelas yang dikembalikan: subtipe markup kembali sebagai MarkupAnnotation, "Link" kembali sebagai LinkAnnotation, dan subtipe lain yang dikenali kembali sebagai Annotation dasar. Gunakan isinstance() terhadap MarkupAnnotation/LinkAnnotation daripada mengasumsikan string subtipe tertentu.
AnnotationFlags nilai tidak tampak mengubah rendering
AnnotationFlags (PRINT, HIDDEN, NO_ZOOM, READ_ONLY, dan serupa) adalah enum standar Python IntFlag untuk menyusun dan menafsirkan bit perilaku anotasi dengan operator | — ini adalah tipe nilai, bukan properti yang ditulis secara otomatis oleh Annotation.add(). Gabungkan flag yang Anda butuhkan dan lewatkan mereka melalui mekanisme properties spesifik tipe yang sama yang digunakan untuk data spesifik subtipe lainnya.
Bekerja dengan halaman yang belum memiliki anotasi
page.annotations selalu merupakan AnnotationCollection yang valid (mungkin kosong) — Anda tidak pernah perlu memeriksa None sebelum memanggil add(), melakukan iterasi, atau memanggil clear().
Pertanyaan yang Sering Diajukan
Subtipe anotasi apa yang didukung oleh Aspose.PDF FOSS untuk Python?
AnnotationType mencantumkan semua 25 subtipe standar PDF 32000-1:2008 Tabel 169, termasuk TEXT, LINK, FREE_TEXT, LINE, SQUARE, CIRCLE, POLYGON, HIGHLIGHT, STAMP, INK, FILE_ATTACHMENT, REDACT, dan lainnya.
Apakah perpustakaan ini mendukung anotasi 3D?
Ya. PDF3DAnnotation, bersama dengan PDF3DArtwork, PDF3DContent, PDF3DView, PDF3DLightingScheme, dan PDF3DRenderMode, memodelkan permukaan anotasi PDF 3D minimal (sebuah persegi panjang, karya seni tersemat, dan tampilan bernama) untuk alur kerja PDF 3D pra-rilis. Lihat referensi PDF3DAnnotation untuk set properti lengkapnya.
Bagaimana cara menghapus anotasi dari halaman?
Panggil page.annotations.delete(index) untuk menghapus satu anotasi berdasarkan posisi, atau page.annotations.clear() untuk menghapus semua anotasi pada halaman.
Apakah saya dapat menyisipkan anotasi pada posisi tertentu alih-alih menambahkannya di akhir?
Ya — AnnotationCollection.insert(index, subtype, rect, contents, title, appearance_normal, properties) mengambil argumen yang sama dengan add() ditambah target index.
Bagaimana warna anotasi direpresentasikan?
Properti color pada Annotation (dan subclass-nya) adalah tuple[float, ...] yang mencocokkan jumlah komponen entri PDF /C (kosong ketika warna tidak disetel) — bukan objek warna khusus.