5.21. Skala, balik, dan pangkas¶
Subbagian sebelumnya semuanya bekerja pada piksel di posisi yang sama tempat mereka dimulai. Keluarga transform mengubah hal itu. Penskalaan mengirim setiap piksel input ke posisi output yang berbeda, mungkin ke beberapa posisi output sekaligus (saat upscaling) atau ke posisi yang dibagi dengan beberapa piksel input lain (saat downscaling). Pembalikan dan rotasi melakukan hal yang sama melalui pemetaan yang berbeda. Pemotongan mempertahankan subset piksel input berbentuk persegi panjang dan membuang sisanya.
Modul image mengekspos keluarga tersebut melalui tiga metode yang berbagi sebagian besar argumen dan perilakunya:
copy()-- menghasilkan salinan citra, kemungkinan diskalakan, dipangkas, atau diubah orientasinya.crop()-- operasi yang sama dengancopy, tetapi dengan ekspektasi bahwa aplikasi akan memilih sub-persegi panjang dari sumber.scale()-- operasi yang sama lagi, dengan ekspektasi bahwa aplikasi akan mengubah ukuran hasil.
Ketiganya berbagi argumen yang sama dan mesin transformasi yang sama; perbedaannya adalah di mana hasil mendarat secara default. copy() menghasilkan citra baru, sementara crop() dan scale() memodifikasi sumber di tempat.
5.21.2. Interpolasi: AREA, BILINEAR, BICUBIC¶
Ketika penskalaan mengirim setiap piksel output ke posisi yang tidak sejajar dengan satu piksel input mana pun, metode harus memilih nilai yang akan ditulis. Tiga flag mengontrol caranya:
image.BILINEAR menginterpolasi antara empat piksel input terdekat yang dibobotkan berdasarkan jaraknya dari posisi output. Hasilnya lebih halus dari tetangga-terdekat, tanpa jaggies yang terlihat pada garis diagonal, tetapi aritmetika tambahan membutuhkan biaya sekitar empat kali lebih banyak dari proses tetangga-terdekat. Pilihan yang tepat untuk sebagian besar pekerjaan upscaling dan untuk faktor skala non-integer.
image.BICUBIC menginterpolasi antara enam belas piksel input terdekat menggunakan kurva kubik, yang menghasilkan hasil yang lebih halus lagi dengan biaya aritmetika yang lebih besar. Kualitas terbaik untuk aplikasi yang sensitif biaya yang membutuhkannya; jarang sepadan dengan komputasi ekstra untuk bingkai langsung yang hanya akan ditampilkan IDE.
image.AREA merata-ratakan setiap piksel input yang jatuh di dalam jejak piksel output -- algoritma yang tepat untuk downscaling. Bilinear dan bicubic adalah interpolator: mereka memperkirakan nilai di antara piksel sumber, yang diperlukan untuk upscaling, tetapi ketika downscaling setiap piksel output mencakup banyak piksel sumber dan interpolator hanya membaca beberapa yang terdekat -- detail yang dilewati muncul kembali sebagai aliasing. image.AREA melipat setiap piksel yang dicakup ke dalam rata-rata.
Algoritma penskalaan default tanpa hint apa pun adalah tetangga-terdekat, yang paling murah dan jawaban yang tepat ketika sumber sudah pada resolusi piksel tujuan.
5.21.3. Orientasi: pembalikan dan rotasi¶
Flag orientasi adalah sekumpulan kecil transformasi boolean yang bebas dikombinasikan satu sama lain dan dengan flag interpolasi:
image.VFLIPmembalik citra secara vertikal (atas menjadi bawah).image.HMIRRORmencerminkannya secara horizontal (kiri menjadi kanan).image.TRANSPOSEmenukar sumbu x dan y (baris menjadi kolom).
Sebagian besar rotasi berasal dari menggabungkan ketiganya. Modul juga mengekspos pintasan bernama:
image.ROTATE_90(=VFLIP | TRANSPOSE)image.ROTATE_180(=HMIRROR | VFLIP)image.ROTATE_270(=HMIRROR | TRANSPOSE)
Dalam kode:
img.copy(hint=image.ROTATE_90, copy_to_fb=True)
5.21.4. Penanganan aspek¶
Ketika rasio aspek sumber tidak cocok dengan persegi panjang yang sedang digambar, tiga flag memutuskan apa yang harus dilakukan dengan ketidakcocokan tersebut:
image.SCALE_ASPECT_KEEP mempertahankan rasio aspek sumber dan memberi letterbox pada hasil -- sumber diskalakan hingga muat di dalam tujuan, dengan piksel kosong (nol) mengisi sisa tujuan. Pilihan yang tepat ketika menjaga sumber tidak terdistorsi lebih penting daripada mengisi seluruh output.
image.SCALE_ASPECT_EXPAND mempertahankan rasio aspek sumber dan memangkasnya -- sumber diskalakan hingga mengisi tujuan, dengan bagian yang meluas melampaui tujuan dipotong. Pilihan yang tepat ketika mengisi seluruh output lebih penting daripada melihat setiap bagian sumber.
image.SCALE_ASPECT_IGNORE mengabaikan rasio aspek dan meregangkan sumber untuk mengisi tujuan, menerima distorsi apa pun yang diperkenalkan. Pilihan yang tepat ketika aplikasi sudah memperhitungkan distorsi -- ketika dimensi tujuan sebenarnya bukan persegi panjang dari adegan yang sama, misalnya.
Default (tidak ada flag aspek yang ditetapkan) sama dengan SCALE_ASPECT_IGNORE: regangkan untuk mengisi. Aplikasi yang peduli dengan rasio aspek menentukan salah satu dari ketiganya secara eksplisit.
5.21.5. Kapan menggunakan yang mana¶
Sebagian besar pengubahan ukuran menggunakan scale() dengan pasangan x_scale / y_scale dan hint interpolasi:
img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)
Sebagian besar rotasi menggunakan panggilan yang sama dengan hint=image.ROTATE_90 atau sejenisnya.
Pemotongan menggunakan crop() dengan roi non-default:
img.crop(roi=(40, 30, 200, 150))
Ketika sumber harus bertahan dari operasi -- mengambil bingkai referensi, mengambil thumbnail dari bingkai yang akan diproses secara destruktif -- copy() menghasilkan hasil sebagai citra baru dan membiarkan sumber tidak tersentuh:
thumbnail = img.copy(x_scale=0.25, y_scale=0.25, hint=image.AREA)
Default tersebut adalah perbedaan nyata di balik ketiga nama: scale dan crop mentransformasi di tempat, copy mengalokasikan. Kata kunci penempatan-hasil menjembatani kesenjangan: copy=True pada scale atau crop mengalokasikan hasil sebagai buffer heap terpisah alih-alih menimpa sumber, dan copy_to_fb=True pada salah satu dari ketiganya menempatkannya di buffer bingkai untuk pratinjau IDE.