5.7. تركيب الصور¶
ترسم العناصر البدائية للرسم في الصفحة السابقة علامات هندسية على الصورة -- خطًا أو مستطيلًا أو نصًا. وهذا يغطي معظم التعليقات التوضيحية التي تحتاج الخوارزمية إلى إظهارها، لكن ليس كلها. ففي بعض الأحيان يكون التعليق التوضيحي نفسه صورة: إطارًا مرجعيًا ملتقطًا لعرضه جنبًا إلى جنب مع الإطار الحالي، أو صورة مصغرة للقطة سابقة تُعرض في زاوية المعاينة، أو قالبًا مخزنًا مسبقًا يُعرض فوق إطار حي للمعايرة. وآلية رسم صورة على أخرى هي دالة واحدة -- draw_image() -- بما يكفي من المعاملات للتعامل مع الموضع والقياس ولوحة الألوان والشفافية التي يحتاجها التركيب الفعلي.
5.7.1. الاستدعاء الأساسي¶
في أبسط صوره، يأخذ draw_image صورة Image أخرى وموضعًا لرسمها فيه:
reference = image.Image("/sdcard/reference.bmp")
img.draw_image(reference, x=10, y=10)
الوجهة هي img؛ والمصدر هو reference؛ يستقر البكسل العلوي الأيسر للمصدر عند (10, 10) من img، وتتبعه بقية بكسلات المصدر نحو اليمين والأسفل من هناك. وتُستبدل بكسلات الوجهة التي يغطيها المصدر ببكسلات المصدر المقابلة؛ أما البكسلات الواقعة خارج نطاق المصدر فتُترك دون تغيير.
إذا امتد المصدر إلى ما بعد حافة الوجهة، فإن الأجزاء التي تتجاوزها تُقتطع بصمت -- وهو السلوك المتسامح ذاته الذي يُظهره set_pixel مع المواضع الخارجة عن المدى. ولا يتعين على شيفرة التطبيق تقييد الموضع ضمن أبعاد الصورة مسبقًا؛ فبإمكانها تمرير الموضع الذي تريده وترك الدالة تتولى الاقتطاع.
5.7.2. تحميل ملف مباشرة¶
يقبل draw_image مسار ملف بدلًا من معامل Image ويحمّل الملف قبل تركيبه:
img.draw_image("/sdcard/reference.bmp", x=10, y=10)
يبدو ذلك وسيلة للتيسير -- سطر واحد بدلًا من سطرين -- وهو كذلك بالفعل، لكن الفرق أكثر من مجرد صياغة. فإنشاء صورة Image من ملف يخصص مخزنًا مؤقتًا يحمل البكسلات المفكوكة الترميز، ويبقى ذلك المخزن المؤقت حتى يحرره جمع المهملات. أما تمرير المسار مباشرة إلى draw_image فيتيح للوحدة فك ترميز الملف إلى مخزن مؤقت مؤقت والتركيب منه ثم تحرير المخزن المؤقت عند عودة الاستدعاء، دون أن تضطر شيفرة التطبيق إلى الاحتفاظ بمرجع إلى صورة Image منفصلة بين الإطارات.
5.7.3. القياس¶
عندما يكون المصدر والوجهة بأحجام مختلفة -- لقطة منخفضة الدقة تُركَّب على لوحة أعلى دقة، أو صورة مصغرة يلزم تحجيمها لتمثل كسرًا محددًا من الإطار -- يتولى معاملا قياس تغيير حجم المصدر أثناء رسمه:
img.draw_image(reference, x=10, y=10, x_scale=2.0, y_scale=2.0)
x_scale و y_scale معاملان عشريان مستقلان؛ تمرير القيمة نفسها لكليهما يقيس بشكل منتظم، وتمرير قيم مختلفة يمدّ المصدر أو يقلّصه على طول محور واحد. ويحدث القياس وقت الرسم؛ فالمصدر reference لا يُعدَّل.
يقرر قناع بتّي من علامات التلميح كيف يستكمل القياس فعليًا بين البكسلات. ينتج image.BILINEAR نتائج أنعم على حساب مزيد من الحساب؛ وينتج image.BICUBIC نتائج أنعم بعد ويكلف أكثر مجددًا؛ ويستخدم الوضع الافتراضي أقرب جار، وهو الأرخص والخيار الصحيح عندما يكون المصدر بالفعل عند دقة بكسل الوجهة. أما علامات معالجة نسبة العرض إلى الارتفاع -- SCALE_ASPECT_KEEP و SCALE_ASPECT_EXPAND و SCALE_ASPECT_IGNORE -- فتقرر ما يجب فعله عندما لا تتطابق نسبة العرض إلى الارتفاع للمصدر مع المستطيل الذي يُرسم فيه.
5.7.4. مزج ألفا¶
افتراضيًا، يستبدل draw_image بكسلات الوجهة ببكسلات المصدر. وعندما يكون الهدف طبقة فوقية شفافة -- بحيث تظهر الوجهة من خلال المصدر -- فإن معامل alpha يتحكم في كيفية مزج الاثنين. فالقيمة alpha=0 تُظهر الوجهة فقط (بلا مصدر)؛ والقيمة alpha=255 هي الافتراضية وتُظهر المصدر فقط (استبدال كامل)؛ والقيم الوسيطة تمزج الاثنين بشكل تناسبي:
img.draw_image(overlay, x=0, y=0, alpha=128)
معامل alpha_palette المنفصل هو آلية ألفا الوحيدة لكل بكسل في الوحدة. وهو يأخذ صورة GRAYSCALE تُستخدم قيمها كقيم ألفا في الموضع المطابق في المصدر -- كخريطة حرارية تتباين قيمة ألفا فيها بحسب شدتها، مثلًا. ويجب توفير قيمة ألفا على هيئة ذلك المعامل المنفصل بتدرج الرمادي؛ فالصورة المصدرية التي تحمل قناة ألفا خاصة بها (صورة PNG ذات شفافية، لنقل) لا تأتي بها تلقائيًا.
5.7.5. منطقة الاهتمام المصدرية ولوحة الألوان¶
يكمل معاملان إضافيان آلية التركيب:
يقيّد
roi=(x, y, w, h)المصدر إلى مستطيل فرعي من نفسه، بحيث يُركَّب ذلك المستطيل وحده على الوجهة. وهو مفيد للاقتصاص داخل الاستدعاء نفسه، دون تجهيز صورة وسيطة مقتصّة.يستبدل
color_paletteقيمة كل بكسل مصدري عبر جدول بحث قبل الرسم -- وهي الآلية ذاتها التي تستخدمهاto_rainbow()وto_ironbow()، وقد عُرضت هنا حتى يمكن إضفاء لوحة ألوان على طبقة فوقية في طريقها إلى الوجهة دون تمريرة تحويل منفصلة.
يتركب كلاهما مع كل شيء آخر في الاستدعاء: القياس وألفا ومعامل mask على جانب الوجهة ومعامل roi على جانب الوجهة الذي يحصر الكتابة في مستطيل من الوجهة.