5.7. Komposisi citra¶
Primitif gambar pada halaman sebelumnya melukis tanda geometris ke suatu citra -- garis, persegi panjang, sepotong teks. Ini mencakup sebagian besar anotasi yang perlu dibuat terlihat oleh suatu algoritma, tetapi tidak semuanya. Terkadang anotasi itu sendiri adalah sebuah citra: bingkai referensi yang diambil untuk ditampilkan berdampingan dengan yang sedang aktif, thumbnail dari pengambilan sebelumnya yang ditampilkan di sudut pratinjau, atau template yang telah tersimpan sebelumnya yang divisualisasikan di atas bingkai langsung untuk kalibrasi. Mekanisme untuk menggambar satu citra ke citra lain adalah satu metode -- draw_image() -- dengan parameter yang cukup untuk menangani posisi, penskalaan, palet warna, dan transparansi yang dibutuhkan komposisi yang sesungguhnya.
5.7.1. Pemanggilan dasar¶
Dalam bentuk paling sederhana, draw_image menerima Image lain dan posisi untuk menggambarnya:
reference = image.Image("/sdcard/reference.bmp")
img.draw_image(reference, x=10, y=10)
Tujuan adalah img; sumbernya adalah reference; piksel kiri atas sumber mendarat di (10, 10) dari img, dan piksel sumber lainnya mengikutinya ke kanan dan ke bawah dari sana. Piksel tujuan yang tertutup oleh sumber ditimpa dengan piksel sumber yang bersangkutan; piksel di luar jangkauan sumber dibiarkan tidak berubah.
Jika sumber melampaui tepi tujuan, bagian yang melampaui batas secara diam-diam dipotong -- perilaku toleran yang sama seperti yang ditunjukkan set_pixel untuk posisi di luar jangkauan. Kode aplikasi tidak harus membatasi posisi ke dimensi citra terlebih dahulu; kode dapat meneruskan posisi yang diinginkan dan membiarkan metode menangani pemotongan.
5.7.2. Memuat berkas secara langsung¶
draw_image menerima jalur berkas sebagai pengganti argumen Image dan memuat berkas sebelum mengomposisikannya:
img.draw_image("/sdcard/reference.bmp", x=10, y=10)
Ini terlihat seperti kemudahan -- satu baris alih-alih dua -- dan memang begitu, tetapi perbedaannya lebih dari sekadar sintaksis. Membuat Image dari berkas mengalokasikan buffer untuk menampung piksel yang telah didekodekan, dan buffer tersebut bertahan hingga pengumpulan sampah melepasnya. Meneruskan jalur secara langsung ke draw_image memungkinkan modul mendekodekan berkas ke dalam buffer sementara, mengomposisikan dari sana, dan melepas buffer ketika panggilan selesai, tanpa kode aplikasi harus menyimpan referensi ke Image terpisah antar bingkai.
5.7.3. Penskalaan¶
Ketika sumber dan tujuan berukuran berbeda -- pengambilan beresolusi rendah yang dikomposi ke kanvas beresolusi lebih tinggi, atau thumbnail yang perlu disesuaikan ke sebagian kecil dari bingkai tertentu -- dua parameter skala menangani pengubahan ukuran sumber saat digambar:
img.draw_image(reference, x=10, y=10, x_scale=2.0, y_scale=2.0)
x_scale dan y_scale adalah float independen; meneruskan keduanya dengan nilai yang sama akan menskalakan secara seragam, dan meneruskan nilai yang berbeda akan meregangkan atau menyusutkan sumber pada satu sumbu. Penskalaan terjadi pada saat menggambar; sumber reference tidak dimodifikasi.
Bitmask dari flag hint menentukan cara penskalaan sebenarnya menginterpolasi antar piksel. image.BILINEAR menghasilkan hasil yang lebih halus dengan biaya komputasi lebih tinggi; image.BICUBIC menghasilkan hasil yang lebih halus lagi dan biayanya lebih besar; default menggunakan nearest-neighbour, yang paling murah dan merupakan pilihan tepat ketika sumber sudah berada di resolusi piksel tujuan. Flag penanganan aspek -- SCALE_ASPECT_KEEP, SCALE_ASPECT_EXPAND, SCALE_ASPECT_IGNORE -- menentukan apa yang harus dilakukan ketika rasio aspek sumber tidak cocok dengan persegi panjang tempat sumber akan digambar.
5.7.4. Pencampuran alpha¶
Secara default, draw_image menggantikan piksel tujuan dengan piksel sumber. Ketika tujuannya adalah overlay transparan -- sehingga tujuan terlihat melalui sumber -- parameter alpha mengontrol bagaimana keduanya dicampur. alpha=0 hanya menampilkan tujuan (tidak ada sumber); alpha=255 adalah default dan hanya menampilkan sumber (penggantian penuh); nilai antara mencampurkan keduanya secara proporsional:
img.draw_image(overlay, x=0, y=0, alpha=128)
Argumen alpha_palette terpisah adalah satu-satunya mekanisme alpha per piksel dari modul. Argumen ini menerima citra GRAYSCALE yang nilainya digunakan sebagai alpha pada posisi yang sesuai di sumber -- misalnya peta panas yang alphanya bervariasi sesuai intensitasnya. Alpha harus disediakan sebagai argumen skala abu-abu terpisah tersebut; citra sumber yang membawa saluran alphanya sendiri (misalnya PNG dengan transparansi) tidak membawanya secara otomatis.
5.7.5. ROI sumber dan palet¶
Dua parameter tambahan melengkapi mekanisme komposisi:
roi=(x, y, w, h)membatasi sumber ke sub-persegi panjang dari dirinya sendiri, sehingga hanya persegi panjang itu yang dikomposi ke tujuan. Berguna untuk memotong di dalam panggilan yang sama, tanpa menyiapkan perantara yang dipotong.color_palettemenggantikan nilai setiap piksel sumber melalui tabel pencarian sebelum menggambar -- mekanisme yang sama yang digunakanto_rainbow()danto_ironbow(), diekspos di sini sehingga overlay dapat dipalet dalam perjalanannya ke tujuan tanpa langkah konversi terpisah.
Keduanya dikombinasikan dengan semua hal lain dalam panggilan: penskalaan, alpha, argumen mask sisi tujuan, dan parameter roi sisi tujuan yang membatasi penulisan ke persegi panjang tujuan.