الداخلية لمحرك معالجة PDF

الداخلية لمحرك معالجة PDF

الداخلية لمحرك معالجة PDF

الفئات Document وPage وAnnotation التي تستخدمها في معالجة PDF اليومية هي واجهة فوق حزمة aspose_pdf.engine منخفضة المستوى. يقوم المحرك بتنفيذ آليات PDF الفعلية: نموذج كائنات COS (Carousel Object Structure) الذي يُبنى عليه كل ملف PDF، المحلل والكاتب الذين يحولان بين كائنات COS وبتات PDF، توليف مظهر التعليقات التوضيحية، رسم الصفحات، الداخلية لمشفّرات الخطوط والصور، والبدائيات التشفيرية وراء تشفير المستند والتوقيعات الرقمية. معظم التطبيقات لا تحتاج أبداً إلى الاستيراد مباشرة من aspose_pdf.engine — لكنه المكان المناسب للبحث عندما تحتاج إلى أدوات مخصصة، فحص PDF جنائي، أو سلوك لا يكشفه API عالي المستوى.


إنشاء مظهر لتعليق توضيحي واحد

التعليقات التوضيحية التفاعلية مثل المربعات والدوائر والطوابع لا تحمل تلقائيًا تدفق مظهر عادي (/AP /N). استدعاء Annotation.generate_appearance يُفعل داخليات توليف المظهر في المحرك لإنشاء واحد عند الطلب من خصائص التعليق التوضيحي.

from aspose_pdf import Document

doc = Document()
doc.pages.add()
ann = doc.pages[0].annotations.add(
    "Square", (100, 100, 200, 200), "", properties={"C": [1, 0, 0], "IC": [0, 1, 0]}
)

print(ann.has_appearance)  # False -- no appearance stream yet
ann.generate_appearance()
print(ann.has_appearance)  # True -- the engine synthesised one
print(b"1 0 0 RG" in ann.appearance_normal)  # True -- red stroke operator
print(b"0 1 0 rg" in ann.appearance_normal)  # True -- green fill operator

إنشاء مظهر دفعي عبر الصفحات والمستندات

AnnotationCollection.generate_appearances يولّد المظاهر لكل تعليق توضيحي مؤهل على الصفحة في نداء واحد، متجاوزًا الأنواع الفرعية التي لا يعرف المحرك كيف يُظهرها (مثل Text):

from aspose_pdf import Document

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

print(page.annotations.generate_appearances())  # 2

Document.generate_appearances يقوم بالمثل عبر كل صفحة في المستند، وهو متطابق — الاستدعاء الثاني لا يفعّل أي شيء بمجرد وجود المظاهر مسبقًا:

from aspose_pdf import Document

doc = Document()
doc.pages.add()
doc.pages.add()
doc.pages[0].annotations.add("Square", (0, 0, 50, 50), "")
doc.pages[1].annotations.add(
    "Line", (0, 0, 50, 50), "", properties={"L": [0, 0, 50, 50]}
)

print(doc.generate_appearances())  # 2 -- one per page
print(doc.generate_appearances())  # 0 -- already generated, no-op

تسطيح التعليقات التوضيحية إلى محتوى الصفحة الثابت

Document.flatten() يرسم مظهر كل تعليق توضيحي مباشرةً في تدفق محتوى الصفحة (كمستدعي كائن XObject Do) ثم يزيل كائن التعليق نفسه، بحيث تُعرض الصفحة بصورة متطابقة في عارضات تتجاهل التعليقات التوضيحية تمامًا:

from aspose_pdf import Document

doc = Document()
doc.pages.add()
doc.pages[0].annotations.add(
    "Square", (100, 100, 200, 200), "", properties={"C": [0, 0, 0]}
)

doc.flatten()

بعد هذه العملية يصبح تدفق محتوى الصفحة أطول مما كان (الآن يحتوي على المربع المدمج) وdoc.pages[0].annotations لم يعد يحتوي على التعليق التوضيحي المسطح.


استخراج مفاتيح التشفير القائمة على كلمة المرور (الإصدار 4 / AES-128)

EncryptionUtils يطبق استخراج مفاتيح معالج الأمان القياسي للـ PDF والبدائيات AES-CBC مباشرةً، مستقلاً عن Document API. هذا مفيد للأدوات المخصصة أو الفحص الجنائي لملفات PDF المشفرة:

import os
from aspose_pdf.engine.encryption import EncryptionUtils

file_id = os.urandom(16)
user_pwd = "mypassword"

# Derive the owner (O) and user (U) key material for Revision 4 (128-bit AES)
o_value = EncryptionUtils.compute_owner_key_v4("owner", user_pwd, 16, 4)
u_value, enc_key = EncryptionUtils.compute_user_key_v4(
    user_pwd, o_value, -4, file_id, 16, 4
)

# Encrypt data with the derived file-encryption key
plaintext = b"Confidential PDF content"
ciphertext = EncryptionUtils.encrypt_aes_cbc(enc_key, plaintext)

# Re-derive the key from the password before trusting it to decrypt
verified_key = EncryptionUtils.verify_password_v4(
    user_pwd, u_value, o_value, -4, file_id, 16, 4
)
print(verified_key is not None)  # True -- password matches

decrypted = EncryptionUtils.decrypt_aes_cbc(verified_key, ciphertext)
print(decrypted == plaintext)  # True

تشفير المحتوى الخام باستخدام AES-CBC

للتلبية المتطلبات ذات المستوى الأدنى، يعمل EncryptionUtils.encrypt_aes_cbc() وdecrypt_aes_cbc() مباشرةً على أي مفتاح بطول 16 أو 24 أو 32 بايت دون المرور باستخراج مفتاح قائم على كلمة المرور على الإطلاق:

import os
from aspose_pdf.engine.encryption import EncryptionUtils

key = os.urandom(32)  # AES-256; 16 and 24-byte keys are also accepted
plaintext = b"Hello, PDF AES 256!"

ciphertext = EncryptionUtils.encrypt_aes_cbc(key, plaintext)
decrypted = EncryptionUtils.decrypt_aes_cbc(key, ciphertext)
print(decrypted == plaintext)  # True

نصائح وأفضل الممارسات

  • يفضَّل استخدام واجهة Document، Page، وAnnotation عالية المستوى لمعالجة المستندات اليومية. حزمة aspose_pdf.engine هي التنفيذ الداخلي الذي تُبنى عليه هذه الفئات — استخدمها فقط عندما تحتاج إلى أدوات مخصصة، فحص جنائي، أو سلوك لا تُظهره الواجهة.
  • طابق معامل revision مع معالج الأمان الذي تستهدفه: يغطي compute_owner_key_v4/compute_user_key_v4 الإصدارات 2–4 (RC4/AES 40-bit و128-bit)، بينما يطبق compute_hash_v5 الخوارزمية للإصدار 5/6 المستخدمة من قبل AES-256. خلط الإصدارات وطول المفاتيح ينتج مفتاحًا خاطئًا بصمت.
  • Document.generate_appearances وAnnotationCollection.generate_appearances متطابقتان (idempotent) — استدعِهما بحذر قبل عرض أو تسطيح مستند لم تقم بإنشائه بنفسك.
  • Document.flatten() عملية تدميرية: تُزيل كل التعليقات التوضيحية التي تُدرجها في محتوى الصفحة. أكمل أي تعديل آخر على التعليقات أولاً، أو اعمل على نسخة.
  • ليس كل نوع فرعي من التعليقات التوضيحية يحتوي على مُولد مظهر مدمج — Text وPopup أمثلة شائعة. تحقق من has_appearance بعد استدعاء generate_appearance() بدلاً من الافتراض بأنه نجح.

مشكلات شائعة

مشكلةالسببالحل
EncryptionUtils.encrypt_aes_cbc/decrypt_aes_cbc يثير خطأ “AES key must be 16, 24, or 32 bytes”تم توفير مفتاح بطول غير صالحأنشئ المفتاح باستخدام os.urandom(16) أو os.urandom(24) أو os.urandom(32)
EncryptionUtils.verify_password_v4 تُرجِع None بدلاً من رفع استثناءكلمة المرور المقدمة لا تتطابق مع القيم المستخرجة من المستند لـ U/Oتحقق صراحةً من None قبل تمرير النتيجة إلى decrypt_aes_cbc
Annotation.generate_appearance تُعيد Falseنوع فرعي للتعليق التوضيحي لا يحتوي على مُولِّد مظهر مدمج (على سبيل المثال Text أو Popup)قدِّم بايتات appearance_normal الخاصة بك، أو اقبل العرض الافتراضي للعارض
استدعاء ثانٍ لـ Document.generate_appearances يُعيد 0الاستدعاء idempotent — يتم تخطي التعليقات التوضيحية التي لديها بالفعل has_appearance == Trueسلوك متوقع، ليس خطأ

FAQ

هل أحتاج إلى الاستيراد من aspose_pdf.engine لمعالجة المستندات اليومية؟

لا. تغطي الفئات Document وPage وAnnotation سير عمل المستندات القياسي. طبقة المحرك هي المكان الذي يتم فيه تنفيذ سلوك هذه الفئات، وهي الأكثر فائدة للأدوات المخصصة أو فحص داخلية PDF مباشرة.

ما الفرق بين Annotation.generate_appearance وAnnotationCollection.generate_appearances؟

الأول يُنشئ تدفق مظهر لتعليق واحد ويعيد bool. الثاني يقوم بنفس العملية لكل تعليق مؤهل في مجموعة (تعليقات الصفحة، أو، عبر Document.generate_appearances، كل صفحة في المستند) ويعيد عدد المظاهر التي أنشأها.

لماذا تأخذ طرق اشتقاق المفتاح معامل revision؟

معالج الأمان القياسي في PDF تطور عبر إصدارات ISO 32000 — الإصدار 2 يستخدم RC4 بحد 40-بت، والإصدارين 3/4 يدعمان RC4 بحد 128-بت أو AES، والإصدارين 5/6 (المستخدمين لـ AES-256) يستخدمان خوارزمية تجزئة مختلفة تمامًا (compute_hash_v5). معامل revision يحدد أي اشتقاق تقوم به طرق EncryptionUtils.

هل يمكنني فحص أو بناء كائنات PDF الخام مباشرةً؟

نعم. aspose_pdf.engine.cos يكشف عن نموذج كائنات COS — PdfObject وPdfDictionary وPdfArray وPdfStream وPdfName والأنواع المرتبطة — التي PdfCosWriter وPdfCosParser تسلسلهما إلى بايتات PDF وتقوم بتحليلها.

أين يحدث تحويل الصفحات إلى صور؟

Document.render_page تُعيد RasterizedPage، كائن على مستوى المحرك يحتوي على أساليب to_png() وto_tiff() وsave() لتحويل صفحة مُعَرضة إلى ملف صورة.


ملخص API Reference

صنف / طريقةوصف
Annotation.generate_appearance(force) -> boolصنّع تدفق المظهر العادي لتعليق واحد عند الطلب
AnnotationCollection.generate_appearances(force) -> intأنشئ مظهرًا دفعيًا لكل تعليق مؤهل على صفحة
Document.generate_appearances(force) -> intإنشاء مظهر دفعي لكل توضيح مؤهل في المستند
Document.flatten() -> Documentدمج مظهر العلامات التوضيحية داخل محتوى الصفحة وإزالة العلامات التوضيحية
Document.render_page(page_index, dpi, scale, background, antialias) -> RasterizedPageتحويل الصفحة إلى نمط نقطي عبر خط أنابيب التصيير في المحرك
RasterizedPageصفحة مُصَغَّرة بتنسيق RGB مضغوط، مع to_png()، to_tiff()، وsave()
GeneratedAppearanceالنتيجة الداخلية لتوليف المظهر: بايتات المحتوى بالإضافة إلى أي موارد ExtGState/الخط المطلوبة
EncryptionUtilsتشفير AES-CBC/RC4 واشتقاق مفتاح معالج الأمان القياسي PDF (الإصدارات 2–6)
PdfObjectفئة أساسية مجردة لكل كائن COS (Carousel Object Structure)
PdfDictionary / PdfArray / PdfStreamأنواع حاويات COS المطبقة التي تشكل شجرة المستند منخفضة المستوى
PdfName / PdfNumber / PdfString / PdfBoolean / PdfNullأنواع قيم COS الأولية
PdfIndirectReferenceإشارة غير مباشرة لـ COS (n g R) إلى كائن آخر
PdfCosWriterيقوم بتسلسل PdfDocument من نوع COS في الذاكرة إلى بايتات PDF
PdfCosParser / LazyPdfObjectStoreيحلّل بايتات PDF إلى كائنات COS، ويُنشئها عند الطلب
IncrementalUpdate / IncrementalWriterإلحاق قسم تحديث تدريجي إلى ملف PDF موجود بدلاً من إعادة كتابته
SimplePdfتمثيل المستند منخفض المستوى الأصلي-Python الذي يُبنى عليه Document API عالي المستوى
TextFragmentAbsorber / TextFragmentCollectionاستخراج مقاطع نصية منخفضة المستوى على مثيل SimplePdf
ImagePlacementAbsorber / ImagePlacementتحديد، حفظ، استبدال أو إخفاء الصور النقطية الموجودة على صفحة
SigningUtilsإنشاء شهادات موقعة ذاتيًا وتواقيع PKCS#7/CAdES للتوقيع الرقمي
DssMaterial / ChainResult / RevocationResult / TimestampInfoدعم التحقق من التواقيع: مواد DSS، نتائج سلسلة الشهادات، فحوصات الإلغاء، والتحقق من طوابع الوقت وفق RFC 3161
StandardFontsالقياسات والترميزات للخطوط القياسية الـ14 في PDF
CidTextCodecترميز وفك ترميز سلاسل العرض للخطوط المركبة (Type0)
Shadingعينة لون RGB عبر التظليل المحوري، الشعاعي، وتظليل القائم على الدوال
Color / Matrixبدائيات اللون وتحويل الأفيـن ثنائي الأبعاد منخفضة المستوى المستخدمة في جميع أرجاء المحرك

انظر أيضاً

 العربية