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. Змішування з прозорістю (alpha blending)¶
За замовчуванням draw_image замінює пікселі призначення пікселями джерела. Коли мета – напівпрозоре накладення, щоб призначення просвічувало крізь джерело, параметр alpha контролює спосіб змішування двох зображень. alpha=0 показує лише призначення (джерело не відображається); alpha=255 – значення за замовчуванням, показує лише джерело (повна заміна); проміжні значення змішують їх пропорційно:
img.draw_image(overlay, x=0, y=0, alpha=128)
Окремий аргумент alpha_palette – єдиний механізм прозорості на рівні пікселів у модулі. Він приймає зображення GRAYSCALE, значення якого використовуються як alpha у відповідній позиції джерела – наприклад, теплова карта, прозорість якої змінюється залежно від інтенсивності. Alpha потрібно передавати як окремий аргумент у відтінках сірого; вихідне зображення, що містить власний альфа-канал (наприклад, PNG із прозорістю), не передає його автоматично.
5.7.5. ROI джерела та палітра¶
Ще два параметри завершують механізм компонування:
roi=(x, y, w, h)обмежує джерело підпрямокутником самого себе, щоб лише цей прямокутник компонувався на призначення. Корисно для обрізання в межах того самого виклику без підготовки проміжного обрізаного зображення.color_paletteпропускає значення кожного пікселя джерела через таблицю підстановки перед малюванням – той самий механізм, який використовуютьto_rainbow()таto_ironbow(), відкритий тут для того, щоб накладення можна було палетизувати під час нанесення на призначення без окремого проходу конвертації.
Обидва параметри поєднуються з усіма іншими параметрами виклику: масштабуванням, alpha, аргументом mask на стороні призначення та параметром roi на стороні призначення, що обмежує запис прямокутником призначення.