تعليقات PDF
تعليقات PDF
Page.annotations يكشف عن AnnotationCollection — عرض قابل للتغيير يشبه التسلسل لكل تعليق على صفحة. كل عنصر هو Annotation (أو الفئات الفرعية MarkupAnnotation / LinkAnnotation)، وبيانات النوع الفرعي مثل نقاط الرباعية، قوائم الحبر، أو الألوان تُقرأ وتُكتب عبر get_property() / set_property() بدلاً من السمات المخصصة.
إضافة تعليقات
AnnotationCollection.add(subtype, rect, contents, title, appearance_normal, properties) ينشئ تعليقًا جديدًا ويضيفه إلى الصفحة. subtype يقبل إما سلسلة نصية عادية ("Text", "Square", "Highlight") أو عضو تعداد AnnotationType.
import aspose_pdf
from aspose_pdf import Document, AnnotationType
doc = Document()
doc.pages.add()
page = doc.pages[0]
# Plain string subtype
page.annotations.add("Text", (100, 100, 200, 200), "Hello")
# AnnotationType enum, with subtype-specific properties
page.annotations.add(
AnnotationType.POLYGON,
(0, 0, 10, 10),
"",
properties={"Vertices": [0, 0, 10, 0, 5, 10]},
)قراءة وتحديث الخصائص
get_property(name, default) يقرأ قيمة خاصة بالنوع الفرعي؛ set_property(name, value) يكتب واحدة، وتعيين خاصية إلى None يزيلها من القاموس properties الخاص بالتعليق.
doc = Document()
doc.pages.add()
page = doc.pages[0]
ann = page.annotations.add(
"Square", (0, 0, 50, 50), "x", properties={"C": [1, 0, 0]},
)
ann.set_property("IC", [0, 0, 1])
print(page.annotations[0].get_property("IC")) # [0, 0, 1]
ann.set_property("C", None) # removes the "C" entry entirely
print("C" in page.annotations[0].properties) # Falseتسمية التعليقات باستخدام AnnotationName
أسماء PDF (مثال: إدخال Name لتعليق Stamp) يتم تمييزها بوضوح عن السلاسل العادية باستخدام AnnotationName، وهو فئة فرعية من aspose_pdf.engine.cos. لا تزال القيمة المخزنة بهذه الطريقة تُقارن مساوية لسلسلة عادية.
from aspose_pdf.engine.cos import AnnotationName
doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add(
"Stamp", (10, 10, 110, 60), "",
properties={"Name": AnnotationName("Approved")},
)الإدراج، الحذف، والمسح
insert(index, subtype, rect, contents, title, appearance_normal, properties) يضع تعليقا جديدا في موضع محدد؛ delete(index) يزيل واحدًا بحسب الفهرس (مرفوعًا IndexError عند فهرس خارج النطاق)؛ clear() يزيل جميع التعليقات من الصفحة.
doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add("Text", (0, 0, 100, 100), "A")
page.annotations.add("Text", (200, 200, 300, 300), "C")
page.annotations.insert(1, "Text", (100, 100, 200, 200), "B")
# order is now: A, B, C
page.annotations.delete(1) # removes "B"
page.annotations.clear() # removes everything remainingإنشاء مظهر التعليقات التوضيحية
Annotation.generate_appearance(force) يبني تدفق المظهر /AP /N لتعليق واحد ويعيد True عندما يكون هناك مُعالج لهذا النوع الفرعي؛ AnnotationCollection.generate_appearances(force) يقوم بنفس العملية لجميع التعليقات على الصفحة في استدعاء واحد ويعيد عدد التعليقات التي تم إنشاؤها فعليًا (يتم تخطي الأنواع الفرعية غير المدعومة).
doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add("Square", (0, 0, 50, 50), "")
page.annotations.add("Circle", (60, 0, 110, 50), "")
page.annotations.add("Text", (0, 60, 20, 80), "") # unsupported subtype -> skipped
generated = page.annotations.generate_appearances()
print(generated) # 2أنواع التعليقات التوضيحية والعلامات
AnnotationType يُعدد أسماء الأنواع الفرعية القياسية في PDF 32000-1:2008 (الجدول 169): TEXT, LINK, FREE_TEXT, LINE, SQUARE, CIRCLE, POLYGON, POLY_LINE, HIGHLIGHT, UNDERLINE, SQUIGGLY, STRIKE_OUT, STAMP, CARET, INK, POPUP, FILE_ATTACHMENT, SOUND, MOVIE, WIDGET, SCREEN, PRINTER_MARK, TRAP_NET, WATERMARK، وREDACT.
AnnotationFlags هو IntFlag يغطي سلوك عرض/تفاعل التعليقات التوضيحية: DEFAULT, INVISIBLE, HIDDEN, PRINT, NO_ZOOM, NO_ROTATE, NO_VIEW, READ_ONLY, LOCKED، وTOGGLE_NO_VIEW.
إصدار تجريبي: تعليقات ثلاثية الأبعاد
PDF3DAnnotation، PDF3DArtwork، PDF3DContent، وPDF3DView نماذج عمل فني ثلاثي الأبعاد مرفق بصفحة — PDF3DAnnotation يحتوي على rect: Rectangle، وartwork: PDF3DArtwork، وbackground_color: Color اختياري. PDF3DArtwork.add_view() يسجل PDF3DView، كلٌ يحمل render_mode (PDF3DRenderMode: SOLID، WIREFRAME، TRANSPARENT) وlighting_scheme (PDF3DLightingScheme: HEADLAMP، WHITE، GRAY، DARK، CUSTOM). توثيق المكتبة نفسه يحدد PDF3DAnnotation كـ “minimal annotation wrapper for prerelease imports” — اعتبر هذه الواجهة في مرحلة مبكرة بدلاً من API ثلاثي الأبعاد مكتمل.
نصائح وأفضل الممارسات
- يفضل استخدام أعضاء تعداد
AnnotationTypeبدلاً من سلاسل الأنواع الفرعية الخام عندما تحتاج القيمة أيضًا إلى المقارنة أو التفرع في أماكن أخرى من الكود. - استدعِ
set_property(name, None)لإزالة الخاصية نهائيًا بدلاً من ترك قيمة قديمة في مكانها — سيختفي الإدخال منpropertiesتمامًا. - قم بتوليد المظهر مجمّعًا باستخدام
AnnotationCollection.generate_appearancesبدلاً من تكرارgenerate_appearance()لكل تعليق؛ تُعيد العدد الفعلي المُولد حتى تتمكن من اكتشاف الأنواع الفرعية المتخطاة/غير المدعومة. delete()والفهرسة فيpage.annotationsكلاهما يبدأ من الصفر؛ تحقق من صحة الفهرس قبل استدعاءdelete()إذا كان من مدخلات المستخدم، لأن فهرس خارج النطاق يثيرIndexError.- غلف قيم أسماء PDF (مثل
Stamp’sName) داخلAnnotationNameلكي تعاد كأسماء PDF بدلاً من سلاسل نصية عادية.
المشكلات الشائعة
| المشكلة | السبب | الإصلاح |
|---|---|---|
generate_appearances() تُرجِع عددًا أقل من عدد التعليقات المُضافة | واحد أو أكثر من الأنواع الفرعية لا يحتوي على مُعالج مظهر مدمج | تحقق من عدد الإرجاع مقابل len(page.annotations)؛ تُتخطى الأنواع الفرعية غير المدعومة بصمت، ولا تُظهر خطأ |
delete(index) يرفع IndexError | المؤشر سالب أو يتجاوز عدد التعليقات الحالية | تحقق من len(page.annotations) قبل استدعاء delete() |
مجموعة الخصائص التي تم تعيينها بـ set_property() لا تظهر بعد إعادة التحميل | تم تعيين الخاصية إلى None، مما يؤدي إلى حذفها بدلاً من تخزينها | استخدم قيمة حقيقية، لا None، عندما يجب أن تبقى الخاصية |
| تنتهي التعليقة المُدخلة في الموقع الخطأ | تم حساب فهرس insert(index, ...) من حالة المجموعة قبل الإدراج | أعد فحص الفهارس بعد كل استدعاء لـ insert() داخل حلقة |
FAQ
كيف أضيف تعليقًا نصيًا عاديًا؟
استدعِ page.annotations.add("Text", (x0, y0, x1, y1), "comment text"). المجموعة المكوّنة من أربعة أرقام هي مستطيل التعليق على الصفحة.
ما الفرق بين Annotation وMarkupAnnotation وLinkAnnotation؟
Annotation هو العرض الحي الذي يُرجَع لأي تعليق على صفحة. MarkupAnnotation هو الأساس لأنواع فرعية بنمط التنسيق (تظليلات، ملاحظات نصية، أشكال) وLinkAnnotation يُحفظ للتعليقات بنمط الروابط؛ كلاهما حاليًا يعرض نفس سطح الطريقة/الخاصية كما في Annotation.
هل يمكنني إزالة خاصية واحدة دون حذف التعليق بالكامل؟
نعم — استدعِ annotation.set_property(name, None); يبقى التعليق نفسه دون تغيير، ويتم إزالة ذلك الإدخال فقط من properties.
هل يفشل AnnotationCollection.generate_appearances إذا لم يكن النوع الفرعي مدعومًا؟
لا. يتخطى الأنواع الفرعية التي لا تمتلك مُظهر مظهر مدمج ويعيد عدد التعليقات التوضيحية التي أنشأ لها مظهرًا فعليًا.
هل فئات التعليقات التوضيحية ثلاثية الأبعاد جاهزة للإنتاج؟
PDF3DAnnotation والأنواع ذات الصلة موثقة كغلاف بسيط للاستيرادات ما قبل الإصدار — تحقق من السلوك مع عارض PDF المستهدف قبل الاعتماد عليها في محتوى ثلاثي الأبعاد للإنتاج.
API Reference ملخص
| فئة/طريقة | وصف |
|---|---|
AnnotationCollection.add | أنشئ وأضف تعليقة جديدة إلى صفحة |
AnnotationCollection.insert | إنشاء وإدراج تعليقة جديدة عند فهرس محدد |
AnnotationCollection.delete | إزالة تعليق توضيحي حسب الفهرس (يُثير IndexError إذا كان خارج النطاق) |
AnnotationCollection.clear | إزالة جميع التعليقات التوضيحية من الصفحة |
AnnotationCollection.generate_appearances | إنشاء تدفقات مظهر /AP /N لكل تعليق توضيحي مدعوم على الصفحة |
Annotation.get_property / set_property | قراءة أو كتابة قيمة خاصية مخصصة للنوع الفرعي |
Annotation.update_properties | إعادة حساب الحالة المستخلصة بعد تعديلات الخصائص المباشرة |
Annotation.generate_appearance | إنشاء تدفق المظهر /AP /N لتعليق واحد |
AnnotationType | تعداد لأسماء الأنواع الفرعية القياسية لتعليقات PDF |
AnnotationFlags | IntFlag لسلوك عرض/تفاعل التعليق |
AnnotationName | الفئة الفرعية str التي تحدد قيمة لتسلسلها كاسم PDF |
PDF3DAnnotation / PDF3DArtwork / PDF3DContent / PDF3DView | نموذج التعليق ثلاثي الأبعاد والرسوم الفنية قبل الإصدار |
PDF3DRenderMode / PDF3DLightingScheme | Enums لوضع عرض ثلاثي الأبعاد ومخطط الإضاءة |