كيف تُخزَّن الصور في PDF؟ XObject والمرشّحات والأقنعة
7 دقيقة للقراءة
كيف تقيم الصورة التي تراها حين تفتح ملف PDF داخل الملف؟ الجواب أعقد مما يبدو للوهلة الأولى: فبيانات الصورة ومعلومات اللون وقناع الشفافية ومعلومات الوضع محفوظة في مواضع منفصلة. نشرح في هذا المقال معمارية تخزين الصور في PDF وكيف تنعكس على عملية الاستخراج.
Image XObject: البنية الأساسية
تُحفَظ الصورة في PDF ككائن يُسمّى Image XObject. ويتألف هذا الكائن من قاموس وتدفق بيانات:
<< /Type /XObject
/Subtype /Image
/Width 2400
/Height 1800
/ColorSpace /DeviceRGB
/BitsPerComponent 8
/Filter /DCTDecode
/Length 458392
>>
stream
...(JPEG data)...
endstream
معاني المفاتيح:
| المفتاح | معناه |
|---|---|
| /Width, /Height | الأبعاد بالبكسل |
| /ColorSpace | فضاء الألوان (DeviceRGB، وDeviceCMYK، وDeviceGray، وIndexed) |
| /BitsPerComponent | عدد البتات لكل قناة (8 عادةً) |
| /Filter | كيفية ترميز البيانات |
| /SMask | مرجع إلى كائن قناع الشفافية، إن وُجد |
| /Decode | هل تُقلَب قيم الألوان أم لا |
والنقطة الحاسمة: هذا القاموس لا يقول أين تقع الصورة في الصفحة. فمعلومات الموضع والمقياس في تدفق محتوى الصفحة:
q
400 0 0 300 100 500 cm % scale and position matrix
/Im1 Do % draw image Im1
Q
والمصفوفة هنا تعني «ارسم هذه الصورة بعرض 400 نقطة وارتفاع 300 نقطة عند الموضع (100,500)».
وهذا التمييز يفسّر سلوك الاستخراج الخام: فالاستخراج يأخذ كائن الصورة، لا وضعها في الصفحة. فالصورة التي تبدو مدوّرة أو مقتصّة أو مصغّرة في الصفحة تأتي في الاستخراج بحالتها الأصلية.
المرشّحات: كيفية ترميز البيانات
يقول المفتاح /Filter بأي ضغط رُمّزت البيانات في التدفق. وأشيعها:
/DCTDecode — ضغط JPEG. والبيانات في التدفق ملف JPEG حقيقي. وهذا اختيار تصميمي ذكي في PDF: فبدل فك ترميز JPEG وإعادة ضغطه عند إضافته إلى PDF يحفظه كما هو. والنتيجة: يبقى الملف صغيراً ولا يحدث فقد إضافي في الجودة.
وتستطيع في الاستخراج الخام حفظ هذه البيانات مباشرة كملف .jpg — بلا أي تحويل.
/FlateDecode — ضغط zlib/deflate بلا فقد. وحين تُفَك بيانات التدفق تخرج مصفوفة بكسلات خام. ويلزم عند الاستخراج تغليف هذه البيانات بصيغة قابلة للاستعمال (PNG عادةً) — لأن مصفوفة البكسلات الخام ليست ملف صورة بذاتها.
/JPXDecode — JPEG 2000. نادر لكنه يُستخدم في بعض أنظمة المسح. ويمكن استخراجه مباشرة كـ .jp2 لكن برامج كثيرة لا تفتح هذه الصيغة.
/CCITTFaxDecode — ضغط الفاكس، للمستندات الممسوحة بالأبيض والأسود. وهو كفؤ جداً؛ فقد يشغل مسح صفحة A4 بضع عشرات الكيلوبايتات. ويشيع تغليفه بصيغة TIFF عند الاستخراج.
/JBIG2Decode — ضغط متقدم للأبيض والأسود. وهو أكفأ من CCITT لكن دعمه أقل انتشاراً.
/LZWDecode — ضغط قديم بلا فقد، ويُستخدم في TIFF وGIF أيضاً.
وصيغة مخرجات أداة الاستخراج متوقفة على هذا المرشّح. فـ DCTDecode ← JPEG، وFlateDecode ← PNG، وCCITTFaxDecode ← TIFF. ولذلك قد تخرج من ملف PDF واحد ملفات بصيغ مختلفة.
فضاءات الألوان ومشكلات الاستخراج
يحدد المفتاح /ColorSpace تفسير لون الصورة:
/DeviceRGB — ألوان الشاشة القياسية. تخرج بلا مشكلة.
/DeviceGray — تدرج رمادي. بلا مشكلة.
/DeviceCMYK — ألوان الطباعة. وهنا تبدأ المشكلة: فكثير من العارضات والمتصفحات لا يفتح صور JPEG بنظام CMYK فتحاً سليماً أو يعرض الألوان مقلوبة. كما أن بعض صور JPEG بنظام CMYK تستخدم عرف الترميز المقلوب من Adobe وتُعلَّم بالمصفوفة /Decode [1 0 1 0 1 0 1 0] — وهذه المعلومة في كائن الصورة لا في ملف JPEG المستخرَج. والنتيجة: قد يبدو الملف الخارج سلبياً.
/Indexed — لون قائم على لوحة. فبيانات الصورة تحتوي فهارس اللوحة وتُحفَظ الألوان الحقيقية في مصفوفة لوحة منفصلة. وإن لم تُطبَّق اللوحة أثناء الاستخراج خرجت الصورة بألوان بلا معنى.
/ICCBased — ملف ألوان مضمّن. ويلزم نقل الملف أيضاً للحصول على اللون الصحيح.
ولذلك قد تبدو ألوان بعض الصور «خاطئة» في الاستخراج الخام. وهذا ليس خطأً؛ بل نتيجة وجود معلومات تفسير اللون خارج ملف الصورة.
الشفافية: آلية SMask
شفافية الصورة في PDF ليست مضمّنة في الصورة نفسها. بل محفوظة في كائن قناع ناعم (soft mask) منفصل:
/SMask 15 0 R
والكائن رقم 15 صورة رمادية بالأبعاد نفسها للصورة الرئيسية. وقيمة كل بكسل تحدد العتامة عند تلك النقطة: 0 شفاف تماماً، و255 معتم تماماً.
وفي الاستخراج الخام يوجَد هذان الكائنان منفصلين ويخرجان كملفين منفصلين. والنتيجة:
- الصورة الرئيسية تأتي معتمة بلا معلومات شفافية. فالخلفية التي كانت تبدو شفافة في PDF قد تبدو الآن سوداء أو بيضاء.
- ملف القناع يبدو بمفرده صورة ظلية بالأبيض والأسود. وهو ليس ملفاً تالفاً؛ بل هو القناع نفسه.
ولاستعادة الشفافية عليك دمج الاثنين في محرر صور: افتح الصورة الرئيسية، وطبّق القناع كقناة ألفا، واحفظ بصيغة PNG.
وثمة أيضاً مفتاح /Mask — وهو يُستخدم لقناع الاستنسل الثنائي (1 بت) أو لإخفاء مفتاح اللون ويعمل بطريقة مختلفة عن SMask لكنه يخلق مشكلة انفصال مماثلة.
لماذا تتجزأ الصور
حالة تتكرر كثيراً في الاستخراج الخام: توجد صورة في الصفحة لكن تخرج عشرة ملفات شرائح منفصلة.
والسبب إدارة الذاكرة لدى منتِج PDF. فبدل معالجة صورة ضخمة جداً كقطعة واحدة، يقرؤها على شكل شرائح أفقية ويكتبها في الملف كذلك. وتصير كل شريحة كائن Image XObject منفصلاً.
وتبدو موحدة في الصفحة لأن تدفق المحتوى يضع كل شريحة في موضع متلاصق تماماً:
q 612 80 0 0 0 712 cm /Im1 Do Q
q 612 80 0 0 0 632 cm /Im2 Do Q
q 612 80 0 0 0 552 cm /Im3 Do Q
ويُلاحَظ هذا السلوك خصوصاً في برمجيات الماسحات وفي مخرجات PDF لبعض البرامج المكتبية.
وللدمج ينبغي وضع الأجزاء بعضها إلى جانب بعض في محرر. وتستطيع تخمين الترتيب من الأرقام في أسماء الملفات لكنه غير مضمون؛ والمطابقة البصرية أوثق.
مفهوم الدقة الفعلية
«دقة» الصورة في PDF ليست خاصية ثابتة. بل تُحسَب من نسبة قيمتين:
الدقة الفعلية = عرض البكسل / العرض الفيزيائي في الصفحة (بالبوصة)
فصورة بعرض 2400 بكسل تُرسَم في الصفحة بعرض 8 بوصات تكون بدقة 300 نقطة/بوصة. والصورة نفسها إن لوئمت مع 4 بوصات صارت 600 نقطة/بوصة.
وهذا يفسّر لماذا يعطي الاستخراج الخام أحياناً صوراً بجودة مفاجئة: فقد تكون الصورة التي تبدو صغيرة في الصفحة عالية الدقة جداً في أصلها. إذ لم تُصغَّر الصورة عند إنتاج PDF بل وُضعت في مساحة صغيرة فقط.
والعكس صحيح أيضاً: فإن كان ملف PDF قد مرّ بعملية ضغط فقد تكون الصور قد خُفضت فعلاً إلى دقة منخفضة ويعطيك الاستخراج الخام تلك الدقة المنخفضة. والبكسل الضائع لا يعود.
الصور غير المرئية
يعطي الاستخراج الخام أحياناً صوراً لم ترها إطلاقاً في الصفحة. والأسباب:
- مناطق خارج مسار الاقتصاص. فقد يكون جزء من الصورة فقط معروضاً؛ والكائن يحمل الصورة كاملة.
- صور غُطّي عليها. فقد يكون عنصر رُسم لاحقاً قد أخفى ما تحته.
- عناصر موضوعة خارج الصفحة. فالمحتوى الواقع خارج MediaBox يبقى في الملف.
- كائنات غير مستخدمة. فقد تبقى في الملف صور لم تعد أي صفحة تشير إليها بعد تحرير ما.
والبند الأخير مهم من زاوية الخصوصية: فلا يكفي وضع شيء فوق صورة لـ«حذفها» من ملف PDF؛ إذ يبقى الكائن في الملف ويجده الاستخراج الخام.
لماذا لا يمكن استخراج الرسوم المتجهية
يجد الاستخراج الخام كائنات Image XObject فقط. والشعارات والمخططات والرسوم البيانية في PDF متجهية عادةً — أي معرّفة بأوامر الرسم في تدفق محتوى الصفحة، وليست كائناً منفصلاً.
و«استخراج» شعار متجهي يحتاج إلى نهج مختلف: تحويل الصفحة إلى SVG وعزل الشعار هناك.
واختبار بسيط للتمييز: كبّر العنصر كثيراً في PDF. فإن تبكسل فهو نقطي (قابل للاستخراج)، وإن بقي حاداً فهو متجهي (غير قابل للاستخراج).
الخلاصة
كل صورة في PDF كائن Image XObject له قاموسه وتدفق بياناته؛ أما معلومات الموضع والمقياس ففي تدفق محتوى الصفحة. وهذا التمييز هو سبب إعطاء الاستخراج الخام الصورةَ الأصلية لا حالتها في الصفحة. وتُحفَظ البيانات بحسب المرشّح إما كملف JPEG حقيقي (DCTDecode) وإما كبكسلات خام (FlateDecode) — وصيغة الاستخراج متوقفة على ذلك. ولأن الشفافية تقيم في كائن SMask منفصل فهي تضيع في الاستخراج ويأتي الاثنان كملفين. وقد تخرج صورة واحدة كملفات كثيرة لأن بعض المنتِجين يقسّم الصور الكبيرة إلى شرائح. والرسوم المتجهية خارج هذه الآلية؛ ويلزم لها التحويل إلى SVG.
الأسئلة الشائعة
هل تقيم صورة JPEG داخل PDF كملف JPEG حقيقي؟
نعم، فالصور المرمّزة بمرشّح DCTDecode بيانات JPEG حقيقية ويمكن استخدامها مباشرة كملف .jpg عند استخراجها من الملف. وهذا اختيار تصميمي ذكي في PDF: فبدل فك ترميز JPEG وإعادة ضغطه يحفظه كما هو، فيبقى الملف صغيراً ولا يحدث فقد إضافي في الجودة. أما الصور المحفوظة بـ FlateDecode فبيانات بكسل خام ويلزم تغليفها بصيغة مثل PNG عند الاستخراج.
كيف تتحدد دقة صورة داخل PDF؟
تُحسَب من النسبة بين أبعاد الصورة بالبكسل (Width/Height) والمساحة الفيزيائية التي تشغلها في الصفحة. فإن كانت صورة بعرض 2400 بكسل تُرسَم في الصفحة بعرض 8 بوصات فالدقة الفعلية 300 نقطة/بوصة. وإن لوئمت الصورة نفسها مع 4 بوصات صارت 600 نقطة/بوصة. أي أن «دقة» الصورة في PDF ليست خاصية ثابتة بل نتيجة متوقفة على مقياس الوضع.
لماذا تكون بعض الصور مقسّمة إلى شرائح أفقية؟
لكفاءة الذاكرة عادةً. فبرمجيات الماسحات وبعض منتِجي PDF تعالج الصور الكبيرة جداً شريحةً شريحة بدل تحميلها كاملة في الذاكرة، وتكتبها في الملف على هذا النحو. وتبدو موحدة في الصفحة لأن الشرائح تُوضَع في مواضع متلاصقة تماماً. والاستخراج الخام يجد كل شريحة ككائن منفصل ويعطيها كملف منفصل.
ما SMask، ولماذا يخرج كملف منفصل؟
SMask (القناع الناعم) صورة رمادية منفصلة تحمل معلومات شفافية صورة ما. وتحدد مقدار شفافية كل بكسل بقيمة بين 0 و255. ولأن الشفافية في PDF محفوظة في هذا الكائن المنفصل لا مضمّنة في الصورة نفسها، يعطي الاستخراج الخام الاثنين كملفين منفصلين وتضيع الشفافية. ولاستعادتها ينبغي دمجهما في محرر.
جرّب ذلك الآن باستخدام PDF'ten Görsel Çıkar (Ham).
جرّب PDF'ten Görsel Çıkar (Ham)