Cara Bekerja dengan Anotasi PDF di Python

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 clause

Langkah 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))  # True

Masalah 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.

Lihat Juga

 Bahasa Indonesia