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 מקובץ מקצה חוצץ (buffer) להחזקת הפיקסלים המפוענחים, וחוצץ זה שורד עד שאיסוף האשפה משחרר אותו. העברת הנתיב ישירות אל 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 אינו משתנה.
מסכת ביטים של דגלי רמז (hint) קובעת כיצד שינוי הקנה מידה בפועל מבצע אינטרפולציה בין פיקסלים. image.BILINEAR מפיק תוצאות חלקות יותר במחיר חישוב רב יותר; image.BICUBIC מפיק תוצאות חלקות אף יותר ועולה עוד יותר; ברירת המחדל משתמשת בשכן הקרוב ביותר (nearest-neighbour), שהיא הזולה ביותר והבחירה הנכונה כאשר המקור כבר נמצא ברזולוציית הפיקסלים של היעד. דגלי טיפול ביחס גובה-רוחב – SCALE_ASPECT_KEEP, SCALE_ASPECT_EXPAND, SCALE_ASPECT_IGNORE – קובעים מה לעשות כאשר יחס הגובה-רוחב של המקור אינו תואם את המלבן שאליו הוא מצויר.
5.7.4. מיזוג אלפא (alpha blending)¶
כברירת מחדל, 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 ולוח צבעים של המקור¶
שני פרמטרים נוספים משלימים את מנגנון ההרכבה:
roi=(x, y, w, h)מגביל את המקור לתת-מלבן בתוך עצמו, כך שרק אותו מלבן מורכב על גבי היעד. שימושי לחיתוך בתוך אותה קריאה, מבלי להכין שלב ביניים חתוך.color_paletteמחליף את הערך של כל פיקסל מקור דרך טבלת חיפוש לפני הציור – אותו מנגנון ש-to_rainbow()ו-to_ironbow()משתמשות בו, חשוף כאן כך ששכבת על תוכל לעבור הלבשת לוח צבעים בדרכה אל היעד ללא מעבר המרה נפרד.
שניהם מתרכבים עם כל השאר בקריאה: שינוי הקנה מידה, האלפא, הארגומנט mask בצד היעד, והפרמטר roi בצד היעד שמתחם את הכתיבה למלבן של היעד.