Cách làm việc với chú thích PDF trong Python
Aspose.PDF FOSS cho Python công khai mọi chú thích trên một trang dưới dạng đối tượng Annotation sống thông qua AnnotationCollection của trang, vì vậy bạn có thể thêm chú thích đánh dấu, liên kết và 3D, kiểm tra các thuộc tính đặc thù loại của chúng, và tạo các luồng hiển thị mà các trình xem PDF cần để render chúng — tất cả từ Python thuần túy. Hướng dẫn này chỉ ra cách cài đặt thư viện, thêm chú thích, đọc lại chúng, và tạo các luồng hiển thị của chúng.
Hướng dẫn từng bước
Bước 1: Cài đặt gói
Cài đặt gói 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 .Xác minh việc cài đặt bằng cách nhập mô-đun aspose_pdf cấp cao nhất, mô-đun này công khai lớp Document được dùng trong các bước phía dưới. Đoạn mã sẽ in aspose_pdf OK khi việc nhập thành công; một ModuleNotFoundError thường có nghĩa là gói đã được cài đặt vào môi trường Python khác so với môi trường đang chạy script của bạn:
import aspose_pdf
print("aspose_pdf OK")Bước 2: Nhập các lớp cần thiết
Nhập Document để chứa PDF, cùng với các lớp chú thích mà bạn sẽ dùng để tạo và kiểm tra các chú thích:
from aspose_pdf import Document
from aspose_pdf.annotations import (
Annotation,
AnnotationType,
AnnotationFlags,
MarkupAnnotation,
LinkAnnotation,
)Bước 3: Thêm một chú thích vào trang
Mỗi Page công khai các chú thích của nó thông qua thuộc tính annotations, một AnnotationCollection. Gọi add(subtype, rect, contents) với tên kiểu phụ, một hình chữ nhật (left, bottom, right, top), và nội dung văn bản của chú thích. Các kiểu phụ đánh dấu chuẩn như "Highlight" được trả về dưới dạng một thể hiện 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 clauseBước 4: Tạo chú thích từ các kiểu phụ enum
AnnotationType liệt kê mọi kiểu phụ chú thích PDF chuẩn (PDF 32000-1:2008, Bảng 169), vì vậy bạn có thể truyền một thành viên enum thay vì một chuỗi thô. Dữ liệu đặc trưng cho loại — chẳng hạn như các đỉnh của đa giác — được đặt trong dict properties và được đọc lại bằng 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]Bước 5: Đọc và lặp qua các chú thích hiện có
AnnotationCollection có thể lặp, vì vậy bạn có thể duyệt mọi chú thích đã có trên một trang — bao gồm cả những chú thích được tải từ một PDF hiện có — và đọc các thuộc tính chung mà mỗi Annotation công khai (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)Bước 6: Tạo Luồng Hiển Thị Chú Thích
Một chú thích được tạo mà không có appearance_normal rõ ràng sẽ không có hiển thị có thể nhìn thấy (/AP /N) cho đến khi một cái được tạo ra. Gọi generate_appearance(force) trên một Annotation duy nhất, hoặc generate_appearances(force) trên toàn bộ AnnotationCollection để tổng hợp mọi luồng hiển thị thiếu trên trang cùng một lúc:
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)")Bước 7: Phân biệt Các Lớp Con của Chú Thích
AnnotationCollection.add() chuyển hướng tới một lớp con cụ thể dựa trên subtype: các subtype kiểu markup (Highlight, Square, Stamp, và các tương tự) trả về dưới dạng MarkupAnnotation, và "Link" trả về dưới dạng LinkAnnotation. Cả hai đều kế thừa mọi phương thức và thuộc tính từ Annotation, vì vậy các kiểm tra isinstance cho phép bạn phân nhánh dựa trên loại chú thích mà không cần kiểm tra trực tiếp các chuỗi subtype:
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)) # TrueCác Vấn Đề Thường Gặp và Cách Khắc Phục
get_property returns None cho một thuộc tính tôi vừa thiết lập
Các khóa properties là tên trường PDF chính xác, phân biệt chữ hoa/thường ("Vertices", "Name", và các tương tự) — một lỗi đánh máy hoặc chữ hoa/thường sai sẽ bị bỏ qua một cách im lặng thay vì gây lỗi. Truyền một đối số default vào get_property(name, default) và kiểm tra nó một cách rõ ràng khi gỡ lỗi một subtype mới.
generate_appearance() returns False
Không phải mọi kết hợp kiểu phụ và thuộc tính đều có thể được tổng hợp thành một luồng hiển thị bởi trình tạo tích hợp. Kiểm tra has_appearance trước khi cho rằng lời gọi đã thành công, và cung cấp một appearance_normal đã được tiền-định dạng (bytes) trực tiếp trên add() cho các kiểu phụ mà trình tạo không hỗ trợ.
Lớp con chú thích không mong đợi sau add()
Chuỗi kiểu phụ (hoặc thành viên AnnotationType) bạn truyền vào quyết định lớp được trả về: các kiểu phụ markup sẽ trả về là MarkupAnnotation, "Link" sẽ trả về là LinkAnnotation, và bất kỳ kiểu phụ nào khác được công nhận sẽ trả về là Annotation cơ bản. Hãy sử dụng isinstance() đối với MarkupAnnotation/LinkAnnotation thay vì giả định một chuỗi kiểu phụ cụ thể.
AnnotationFlags các giá trị dường như không thay đổi việc hiển thị
AnnotationFlags (PRINT, HIDDEN, NO_ZOOM, READ_ONLY, và các tương tự) là một enum chuẩn Python IntFlag để tạo và diễn giải các bit hành vi của chú thích với toán tử | — đây là một kiểu giá trị, không phải thuộc tính mà Annotation.add() ghi tự động. Kết hợp các cờ bạn cần và truyền chúng qua cùng cơ chế properties đặc thù cho kiểu được dùng cho dữ liệu kiểu phụ khác.
Làm việc với một trang chưa có chú thích nào
page.annotations luôn là một AnnotationCollection hợp lệ (có thể rỗng) — bạn không bao giờ cần kiểm tra None trước khi gọi add(), lặp lại, hoặc gọi clear().
Câu hỏi thường gặp
Các kiểu phụ chú nào mà Aspose.PDF FOSS cho Python hỗ trợ?
AnnotationType liệt kê tất cả 25 kiểu phụ chú tiêu chuẩn của PDF 32000-1:2008 Bảng 169, bao gồm TEXT, LINK, FREE_TEXT, LINE, SQUARE, CIRCLE, POLYGON, HIGHLIGHT, STAMP, INK, FILE_ATTACHMENT, REDACT, và các kiểu khác.
Thư viện này có hỗ trợ các chú thích 3D không?
Có. PDF3DAnnotation, cùng với PDF3DArtwork, PDF3DContent, PDF3DView, PDF3DLightingScheme, và PDF3DRenderMode, mô hình một bề mặt chú thích PDF 3D tối thiểu (một hình chữ nhật, tác phẩm nhúng và các góc nhìn được đặt tên) cho quy trình làm việc PDF 3D trước phát hành. Xem tham chiếu PDF3DAnnotation cho bộ thuộc tính đầy đủ của nó.
Làm thế nào để tôi xóa một chú thích khỏi trang?
Gọi page.annotations.delete(index) để xóa một chú thích theo vị trí, hoặc page.annotations.clear() để xóa mọi chú thích trên trang.
Tôi có thể chèn một chú thích vào vị trí cụ thể thay vì thêm vào cuối không?
Có — AnnotationCollection.insert(index, subtype, rect, contents, title, appearance_normal, properties) nhận các đối số giống như add() cộng với mục tiêu index.
Màu sắc của chú thích được biểu diễn như thế nào?
Thuộc tính color trên Annotation (và các lớp con của nó) là một tuple[float, ...] khớp với số thành phần của mục nhập PDF /C (rỗng khi màu chưa được đặt) — không phải là một đối tượng màu riêng biệt.