Contoh penggunaan ImageMagick -- efek pemetaan gambar
- Kata pengantar dan indeks contoh penggunaan ImageMagick
- Pengantar pemetaan gambar
- Mendistorsi gambar dengan pemetaan gambar
- Peta pencarian distorsi absolut
- Peta distorsi absolut
- Komposisi distorsi absolut
- Meninjau ulang peta distorsi no-op
- Masalah pada peta distorsi
- Menetapkan piksel tak terdefinisi dengan mask
- Gambar distorsi terpadu
- Peta distorsi jam pasir
- Peta distorsi bola
- Peta distorsi busur lingkaran
- Operator komposisi Displace
- Contoh perpindahan sederhana
- Menggambar grafik perpindahan
- Perpindahan area
- Pantulan air beriak
- Peta perpindahan 2 dimensi
- Perpindahan silindris
- Blur dengan rasio aspek variabel
- Blur dengan sudut variabel
Mendistorsi atau memodifikasi gambar memakai semacam gambar 'pemetaan' sekunder yang mengendalikan prosesnya. Entah itu mengganti warna, menerapkan blur bervariasi pada gambar, atau mendistorsi gambar dengan menentukan koordinat sumber secara absolut maupun relatif.
Pengantar
Seperti terlihat pada bagian sebelumnya tentang Komposisi, Warping sederhana, dan Distorsi, gambar dapat dimodifikasi dengan banyak cara berbeda. Namun semuanya terbatas pada metode tertentu yang sudah tertanam di dalam ImageMagick. Distorsi gambar bahkan bisa dirakit sendiri memakai 'operator DIY FX', atau nilai gambar dapat diubah langsung memakai operator seperti Evaluate atau Function, atau bahkan berbagai operator Level. Namun distorsi memerlukan banyak perhitungan (dan waktu) untuk menyelesaikan tugasnya, dan bila tugas yang sama hendak dijalankan atas banyak gambar, membiarkan IM mengulang semua perhitungan itu benar-benar membuang waktu. Sisi lainnya, sangat sulit membatasi efek distorsi secara bebas. Distorsi yang hendak diterapkan tidak bisa begitu saja disunting atau dimodifikasi. Kendalinya terbatas. Pemetaan gambar berbeda. Sebuah gambar 'pemetaan' tambahan dipakai untuk mengendalikan bagian mana dari sebuah gambar yang akan dimodifikasi, seberapa besar, dan dengan cara apa. Ia tidak harus memodifikasi seluruh gambar, dan tidak harus memodifikasinya dengan cara yang sudah ditentukan atau diprogram sebelumnya. Anda dapat membuat 'peta' yang memodifikasi gambar dengan cara APA PUN yang mungkin, tanpa batas. Pemetaan itu juga dapat disunting atau dimodifikasi lebih lanjut, untuk menyesuaikan atau membatasi efeknya, membuatnya lebih rumit, dengan menggabungkan beberapa peta, atau sekadar menghaluskan atau mem-blur efeknya. Dan akhirnya pemetaan itu dapat disimpan untuk dipakai lagi nanti. Gambar 'peta' itulah yang mengendalikan hasilnya. Karena modifikasinya dikendalikan oleh 'peta', biasanya sangat sedikit perhitungan yang perlu dikerjakan ImageMagick, sehingga 'pemetaan gambar' pada umumnya sangat cepat. Ia juga dapat diulang , karena peta yang sangat rumit itu dapat diterapkan pada berapa pun jumlah gambar dan menghasilkan modifikasi yang persis sama. Artinya, peta itu dapat diterapkan pada satu direktori penuh gambar dengan sangat cepat. Pada intinya, yang dilakukan pemetaan gambar adalah memindahkan matematika yang lambat dan rumit dari suatu efek, dari satu gambar tertentu ke gambar 'peta' yang lebih umum. Setelah 'peta' itu dibuat, ia dapat diterapkan pada banyak sekali gambar nyata dengan sangat cepat.
Apa itu peta gambar
Gambar pemetaan pada dasarnya adalah "Look Up Table" atau LUT yang mendefinisikan bagaimana suatu efek diterapkan pada gambar, piksel demi piksel. Artinya, apakah suatu efek diterapkan dan seberapa besar, sepenuhnya dikendalikan oleh peta gambar. Pada hakikatnya gambar adalah larik nilai, dan makna nilai-nilai itu bergantung pada proses pemetaan yang sedang diterapkan. Nilai tersebut bisa menunjukkan...
- nilai pengganti langsung (pencarian warna),
- dari gambar mana suatu warna harus diambil (masking gambar),
- seberapa terang atau gelap sebuah piksel harus dibuat (penyorotan),
- menentukan koordinat sumber (distorsi),
- atau lokasi relatif terhadap posisi saat ini (perpindahan).
- seberapa besar piksel di lokasi ini harus di-blur
Banyak di antaranya sudah kita lihat di Komposisi gambar, dan dalam arti tertentu pemetaan gambar hanyalah cara lain untuk menggabungkan beberapa gambar. Nyatanya banyak teknik pemetaan gambar diimplementasikan begitu saja sebagai metode compose khusus! Ingat saja bahwa komposisi gambar yang sesungguhnya sekadar penumpukan dua gambar berwarna nyata dengan berbagai cara (khususnya Metode komposisi alpha Duff-Porter). Pemetaan gambar secara lebih umum melibatkan gambar khusus yang memodifikasi sebuah gambar dengan cara istimewa. Bagian tersulit dari pemetaan gambar adalah membuat 'peta' tertentu untuk efek tertentu. Dan di situlah sebagian besar kerja, upaya, dan teknik yang ada di halaman ini bermuara. Namun begitu peta itu ada, ia dapat dipakai berkali-kali dengan banyak gambar berbeda dengan sangat cepat.
Mendistorsi gambar dengan pemetaan gambar
Dengan berbagai operator distorsi yang diuraikan pada bagian sebelumnya di IM Examples (seperti Warping gambar sederhana dan Distorsi gambar umum), Anda terbatas pada jenis distorsi yang sudah diprogramkan ke dalam pustaka grafis IM, umumnya memakai persamaan dan rumus matematis tertentu. Namun ada kalanya distorsi sendiri ingin dirancang dengan cara yang lebih bebas dan kurang matematis. Misalnya untuk membuat distorsi yang lebih rumit, seperti memetakan gambar ke bentuk tertentu, atau dengan efek lensa rumit tertentu, yang lebih mudah digambar daripada didefinisikan secara matematis. Kadang Anda hanya ingin dapat mengulang distorsi itu atas sejumlah besar gambar dan menghindari perhitungan ulang berkali-kali. Solusinya adalah menghitung distorsi itu di muka, lalu menyimpannya sebagai look-up table (LUT) khusus dalam bentuk gambar grayscale. Artinya, untuk setiap piksel keluaran, kita mencari nilainya di LUT, lalu memakai nilai itu untuk mencari warna dari gambar sumber. Jadi diperlukan tiga langkah.
- Cari setiap piksel tujuan di dalam LUT
- Petakan nilai LUT ke lokasi gambar sumber (dua metode)
- Cari warnanya dari gambar sumber
Karena sebuah gambar dipakai sebagai 'lookup table' distorsi, peta distorsi dapat dibuat atau dimodifikasi memakai penyunting gambar seperti 'Gimp' atau 'PhotoShop', sehingga Anda bebas membuat distorsi yang benar-benar rumit dan menarik. Namun ingat, sama seperti semua metode distorsi lain yang sudah kita lihat, pencarian ini diterapkan sebagai Pemetaan piksel terbalik. Artinya, untuk setiap piksel pada gambar tujuan, kita mencari warna piksel dari gambar sumber memakai metode distorsi yang sedang diterapkan. Dalam hal ini metodenya adalah mencari koordinat sumber dari gambar Look-up Table yang diberikan.
Sekarang ada dua cara memakai peta gambar untuk menentukan di mana suatu warna dicari pada gambar sumber... absolut atau relatif. Dengan pencarian koordinat absolut, sebuah Peta distorsi mengubah nilai warna LUT langsung menjadi koordinat pada gambar sumber tempat warna itu diambil. Tidak peduli di mana letak warna itu di dalam LUT, setiap warna merujuk ke titik pencarian yang persis. Gambar LUT distorsi akan memiliki gradien warna, tetapi warping atau distorsi apa pun atas gradien itu akan mencapai efek yang sama ketika petanya diterapkan. Dengan pencarian koordinat relatif, sebuah Peta perpindahan memakai nilai warna untuk menggeser koordinat saat ini guna menentukan lokasi pada gambar sumber tempat warna dicari. Ini berarti dipakai gambar LUT abu-abu murni, dengan area yang lebih terang dan lebih gelap mendefinisikan bagaimana piksel digeser atau dipindahkan oleh peta itu, terlepas dari letaknya di dalam peta. Kedua metode punya kelebihan dan kekurangan, seperti akan Anda lihat.
Peta pencarian distorsi absolut
Membuat peta LUT distorsi absolut adalah yang lebih sederhana dari kedua metode itu, baik untuk dipahami, dibuat, maupun diterapkan. Namun, seperti akan Anda lihat, ia punya kelemahan yang sangat serius sehingga kurang praktis dibanding Peta perpindahan relatif. Warna pada titik mana pun di dalam 'peta distorsi' langsung merujuk ke sebuah lokasi pada gambar sumber. Artinya, gradien grayscale di seluruh 'peta' mendefinisikan 'tekstur' yang akan ditempatkan di lokasi itu. Sekarang bayangkan gambar petanya sebenarnya adalah gambar objek rumit seperti kaus, dengan lipatan dan riak yang rumit. Bila kaus itu punya gradien di atasnya, gambar datar apa pun dapat dipetakan ke kaus tersebut. Itulah kekuatan peta distorsi absolut. Setiap piksel 'hitam' pada gambar LUT (nilai warna 0) akan dianggap sebagai piksel paling kiri atau koordinat X '0' dari gambar sumber, sedangkan apa pun yang 'putih' pada LUT (nilai 1) dianggap sebagai piksel paling kanan (lebar gambar sumber). Perhatikan bahwa LUT ini hanya akan mencari posisi X atau horizontal dari warna pada gambar sumber. Ia tidak mengubah tinggi atau posisi Y warna. Jadi mari kita coba dengan gradien horizontal grayscale polos sederhana sebagai LUT.
magick koala.gif \( -size 75x75 gradient: -rotate 90 \) \
-fx 'p{v*w,j}' distort_noop.gif
Perhatikan bahwa ini tidak menghasilkan perubahan nyata dalam pemetaan gambar sumber ke gambar tujuan. Itu karena koordinat X yang kita cari dari peta distorsi persis sama dengan posisi tempat kita mencari warnanya. Dengan sekadar membalik gradiennya, pencarian pikselnya pun ikut terbalik dan menghasilkan gambar cermin. Artinya, putih ada di kiri dan 'hitam' di kanan, dengan gradien horizontal melintasi gambar.
magick koala.gif \( -size 75x75 gradient: -rotate -90 \) \
-fx 'p{v*w,j}' distort_mirror_x.gif
Bila gradien asli itu kita ambil lalu dimampatkan memakai operator penguat kontras, kita bisa mendapatkan distorsi yang jauh lebih berguna.
magick -size 75x75 gradient: -rotate 90 \
-sigmoidal-contrast 8,50% map_compress.gif
magick koala.gif map_compress.gif -fx 'p{v*w,j}' distort_compress.gif
Perhatikan bahwa sisi-sisi distorsinya meregang sementara bagian tengahnya memampat. Ini dapat diperluas ke dua dimensi dengan memakai 2 peta distorsi, satu untuk menyesuaikan koordinat X, satu lagi untuk koordinat Y.
magick map_compress.gif -rotate 90 map_compress_y.gif
magick koala.gif map_compress.gif map_compress_y.gif \
-fx 'p{u[1]*w,u[2]*h}' distort_compress_2D.gif
Seperti Anda lihat, langkah di atas menciptakan ulang variasi metode implode, meski hanya dengan memampatkan gambar sepanjang sumbu X dan Y (serentak), bukan secara radial seperti yang dilakukan operator Implode. Kuncinya di sini: apa pun yang Anda lakukan pada peta distorsi absolut, itulah yang akan terjadi pada gambar akhir dari gambar apa pun yang Anda terapkan padanya. Itulah kekuatan peta distorsi.
Metode komposisi 'Distort'
Sejauh ini kita memakai FX, operator DIY umum untuk menerapkan peta distorsi absolut. Cara ini memungkinkan penyesuaian yang persis atas apa yang dikerjakan, tetapi juga sangat lambat. Operator komposisi "Distort" mengodekan rumus yang sangat mirip dengan yang kita pakai di atas. Hanya saja ia diimplementasikan dengan cara yang juga membuatnya sedikit lebih selaras dengan operator komposisi "Displace" yang akan kita lihat nanti di Peta perpindahan relatif.
Jadi mari kita ulangi contoh 'implode' terakhir memakai komposisi "Distort".
magick koala.gif map_compress.gif map_compress_y.gif \
-compose Distort -define compose:args=37.5x37.5 -composite \
distort_compose.gif
Perhatikan pemakaian "pengaturan define" "compose:args" di atas. Nilai ini adalah pengali terhadap gradien LUT yang dipakai (berpusat pada abu-abu sempurna). Nilai '37.5' yang dipakai adalah setengah lebar dan tinggi gambar (75 piksel). Pengali itu dapat diubah untuk memperbesar atau memperkecil skala keseluruhan distorsi. Bila nilai "compose:args" TIDAK didefinisikan, ia akan memakai nilai yang benar secara default. Bila nilainya disetel nol, tidak ada distorsi yang diterapkan pada arah tersebut. Bila argumen komposisi ingin disetel secara otomatis, metode setara Set "option:" berikut dapat dipakai untuk menghitungnya... |
magick koala.gif map_compress.gif map_compress_y.gif \
-set option:compose:args '%[fx:w/2]x%[fx:h/2]' \
-compose Distort -composite \
distort_compose_set.gif
![[IM Output]](../static/img/mapping/distort_compose_set.gif)
Atau hapus definisinya agar IM yang menghitung nilai yang benar (untuk Distort 2D)... |
magick koala.gif map_compress.gif map_compress_y.gif \
-compose Distort -define compose:args='' -composite \
distort_compose_default.gif
Peta distorsi no-op
Sebelum melangkah lebih jauh, saya ingin mundur sejenak dan melihat lagi contoh 'noop' di atas. Contoh itu sebenarnya sedikit mem-blur gambarnya, karena rumus yang saya uraikan sesungguhnya belum tepat. Mendapatkan salinan 'no-op' dari aslinya adalah uji yang baik untuk memastikan matematika distorsi Anda benar.
Artinya, bila diberi gradien sempurna, setiap piksel dapat dipetakan dari gambar sumber ke gambar tujuan. Artinya, nilai 'putih' LUT (atau 1.0) akan dipetakan persis ke piksel paling kanan (atau paling bawah) pada gambar tujuan.
Untuk menguji distorsi no-op kita memakai 'gambar kotak-kotak piksel' (mis. "pattern:gray50") karena gambar itu akan menampakkan distorsi apa pun, dan dengan demikian masalah apa pun pada matematika yang diterapkan. Jadi mari kita coba terapkan distorsi no-op pada metode yang sudah kita pakai sejauh ini... |
magick -size 75x75 pattern:gray50 \
\( gradient: -rotate 90 \) \( gradient: -flip \) \
-fx 'p{u[1]*w,u[2]*h}' distort_fx_check.gif
magick -size 75x75 pattern:gray50 \
\( gradient: -rotate 90 \) \( gradient: -flip \) \
-set option:compose:args '%[fx:w/2] x %[fx:h/2]' \
-compose Distort -composite distort_compose_check.gif
![[IM Output]](../static/img/mapping/distort_compose_check.gif)
Seperti Anda lihat, KEDUA metode gagal menghasilkan ulang gambar 'kotak-kotak piksel' itu. Meski kegagalannya sedikit berbeda karena cara koordinatnya dihitung. Yang terjadi adalah faktor penskalaan dari pencarian warna ke koordinat piksel meleset 1 piksel. Untuk rincian penyebabnya lihat Distorts, koordinat gambar vs koordinat piksel. | _Distorsi FX berpusat pada sudut kanan atas (lokasi piksel 0,0), dan menghasilkan piksel virtual ganda di sepanjang tepi bawah dan kanan. Itu karena ia sama sekali tidak berusaha mengubah pusat penskalaan, dari warna pencarian ke koordinat gambar yang dipakai untuk pencarian sesungguhnya. Akibatnya piksel hitam tetap berpusat di piksel 0,0, meski penskalaannya salah.
Operator compose "Distort" menggeser koordinatnya sehingga nol berada di pusat gambar, sebelum penskalaan diterapkan. Ia melakukannya sebagai bagian dari penskalaan untuk 'peta perpindahan' (lihat nanti). Akibatnya penskalaan yang tidak akurat itu menarik tepi gambar ke dalam sejauh 1/2 piksel di setiap tepi, sementara bagian tengah gambar tetap benar._
Berikut versi 'no-op sempurna' yang sudah dikoreksi untuk peta distorsi absolut, yang pada dasarnya memakai koordinat gambar (lebar dan tinggi dikurangi satu) saat menghitung faktor penskalaan antara warna dan koordinat. |
magick -size 75x75 pattern:gray50 \
\( gradient: -rotate 90 \) \( gradient: -flip \) \
-fx 'p{u[1]*(w-1),u[2]*(h-1)}' distort_fx_check_correct.gif
magick -size 75x75 pattern:gray50 \
\( gradient: -rotate 90 \) \( gradient: -flip \) \
-set option:compose:args '%[fx:(w-1)/2] x %[fx:(h-1)/2]' \
-compose Distort -composite distort_compose_check_correct.gif
![[IM Output]](../static/img/mapping/distort_compose_check_correct.gif)
Sebenarnya nilai default "compose:args", bila tidak didefinisikan, memang memakai nilai penskalaan yang benar. |
magick -size 75x75 pattern:gray50 \
\( gradient: -rotate 90 \) \( gradient: -flip \) \
-compose Distort -define compose:args='' -composite \
distort_compose_default_check.gif
![[IM Output]](../static/img/mapping/distort_compose_default_check.gif)
Namun perlu ditegaskan bahwa ketidakakuratan kecil ini biasanya tidak begitu penting saat memakai distorsi, sehingga perbedaan kecil apa pun umumnya diabaikan. Ingat saja hal ini supaya Anda tahu ketika suatu saat perbedaan itu benar-benar penting.
Masalah pada peta distorsi
Mari kita lanjutkan distorsi gambar dengan mencoba rotasi. Membuat peta yang diputar untuk keperluan ini bisa sedikit rumit, tetapi bisa dilakukan...
magick -size 75x75 gradient: -background black -rotate 45 \
-gravity center -crop 75x75+0+0 +repage map_rot45_x.png
magick map_rot45_x.png -rotate 90 map_rot45_y.png
magick koala.gif map_rot45_x.png map_rot45_y.png \
-compose Distort -composite distort_rot45.gif
Dan kini kita punya cara lain untuk memutar gambar apa pun. Masalah terbesar teknik ini: karena peta distorsi kita dibuat dengan rotasi, muncul beberapa piksel berwarna aneh di sepanjang sisi tepi diagonal. Pada contoh terakhir hal ini menambahkan sejumlah piksel acak dalam satu garis di sepanjang sudut kanan bawah gambar. Warna 'acak' itu adalah nilai anti-aliasing yang ditambahkan rotasi untuk menghasilkan gambar yang 'lebih baik'. Namun untuk peta distorsi, piksel tepi hasil anti-aliasing dapat menimbulkan masalah serius. Sekarang kita bisa mencoba mendefinisikan warna di tepi gambar LUT yang diputar dengan lebih baik. Dalam hal ini kita dapat membuat gambar gradien yang lebih besar, lalu memangkas hasil rotasinya ke ukuran yang benar.
magick -size 100x20 xc:white xc:black -size 115x75 gradient: \
+swap -append -rotate 45 \
-gravity center -crop 75x75+0+0 +repage map_rot45b_x.png
magick map_rot45b_x.png -rotate 90 map_rot45b_y.png
magick koala.gif map_rot45b_x.png map_rot45b_y.png \
-compose Distort -composite distort_rot45_better.png
Dengan begitu semua piksel di dalam LUT kini terdefinisi dengan benar tanpa anti-aliasing. Ini memunculkan masalah lain yang sedikit berbeda. Semua piksel pada gambar akhir sudah terdefinisi dengan benar, tetapi sebagian piksel seharusnya tidak menjadi bagian dari gambar akhir. Piksel itu tidak punya makna nyata pada gambar hasil. Inilah masalah terbesar dalam memakai LUT untuk menentukan koordinat absolut yang diambil dari gambar sumber. Tidak ada cara untuk menentukan apa yang harus dilakukan IM pada area tak terdefinisi tersebut.
Menetapkan piksel tak terdefinisi dengan mask
Cara yang lebih umum untuk memecahkan masalah 'piksel tak terdefinisi' adalah mendefinisikan peta tentang piksel mana yang benar-benar merupakan hasil distorsi yang sah. Dengan kata lain, sebuah gambar masking. Misalnya...
magick -size 75x75 xc:white -background black -rotate 45 \
-gravity center -crop 75x75+0+0 +repage map_rot45b_m.png
magick distort_rot45_better.png map_rot45b_m.png \
-alpha off -compose CopyOpacity -composite distort_rot45_masked.png
Kini ada tiga gambar yang terlibat dalam peta distorsi, dan hasilnya memang menjadi rumit. Tentu saja dalam situasi biasa Anda mungkin tidak perlu sejauh itu, tetapi untuk kasus umum memang perlu.
Gambar distorsi terpadu
Mungkin Anda memperhatikan bahwa ketiga peta itu semuanya gambar grayscale. Ini berarti cukup masuk akal untuk menggabungkan semua peta itu menjadi satu gambar peta distorsi. Misalnya, mari kita petakan 'peta distorsi X' ke kanal 'red', 'peta Y' ke 'green', dan mask-nya ke kanal 'alpha' atau transparansi, sehingga lebih mudah ditangani.
magick map_rot45b_x.png map_rot45b_y.png \( map_rot45b_m.png -negate \) \
-alpha off -channel RGA -background black -combine map_rot45u.png
| Kanal 'blue' pada Gambar kanal gabungan tidak didefinisikan, sehingga nilainya diambil dari warna "-background" saat ini, yang di atas saya setel ke 'black' atau nilai nol.
Sekarang mari kita terapkan peta distorsi terpadu ini pada gambar koala kita. Sayangnya ini memerlukan dua langkah pemrosesan gambar, satu untuk mendistorsi gambar dan satu untuk mem-mask hasilnya.
magick koala.gif -alpha set map_rot45u.png \
\( -clone 0,1 -fx 'p{v.r*w,v.g*h}' \
+clone -compose Dst_In -composite \) -delete 0,1 \
distort_rot45_unified.png
Metode komposisi "Distort" juga dapat dipakai langsung dengan gambar peta distorsi terpadu itu... |
magick koala.gif -alpha set map_rot45u.png \
-compose Distort -define compose:args='' -composite \
distort_rot45_compose.gif
![[IM Output]](../static/img/mapping/distort_rot45_compose.gif)
Masih ada satu kanal yang belum terpakai (blue) pada gambar 'peta distorsi terpadu'. Satu pemakaian yang masuk akal untuknya adalah sebagai sarana menambahkan sorotan dan bayangan pada gambar yang didistorsi. (Lihat Overlay highlights). Teknik ini dibawa selangkah lebih jauh pada contoh Peta distorsi bola di bawah.
Peta distorsi jam pasir
Waktu itu saya menginginkan peta distorsi satu dimensi yang menskalakan setiap baris gambar secara berbeda berdasarkan ketinggian baris tersebut. Semacam distorsi cermin rumah hantu di pasar malam yang membuat orang gemuk tampak sangat kurus. Dengan kata lain, semacam distorsi jam pasir. Ini gambar LUT yang cukup rumit, dan setelah banyak coba-coba saya sampai pada ekspresi berikut untuk menghasilkan peta gradien yang berubah menurut tinggi namun linier secara horizontal. |
magick -size 100x100 xc: -channel G \
-fx 'sc=.15; (i/w-.5)/(1+sc*cos(j*pi*2/h)-sc)+.5' \
-separate map_hourglass.png
![[IM Output]](../static/img/mapping/map_hourglass.png)
| Saat menghasilkan gradien grayscale, operator -fx dapat dibuat 3 kali lebih cepat hanya dengan memintanya menghasilkan satu kanal warna saja, seperti kanal 'G' atau green pada contoh di atas. Kanal ini kemudian dapat Dipisahkan untuk membentuk gambar grayscale yang dibutuhkan. Ini bisa berarti lonjakan kecepatan yang sangat besar, terutama ketika memakai rumus "-fx" yang sangat rumit.
'sc' adalah faktor penskalaan untuk jam pasir (nilainya berkisar dari 0 sampai 0.5), dan memungkinkan Anda menyesuaikan besar distorsinya. Sekarang mari kita terapkan peta ini pada gambar bawaan "rose:". Perhatikan bahwa peta berukuran 100x100 piksel itu tidak cocok dengan gambar 70x46 piksel. Ini menyulitkan, karena kita perlu menskalakan piksel saat ini pada gambar sumber sebesar nilai yang sesuai agar cocok dengan peta distorsi yang diberikan, untuk mencari lokasi warna piksel tersebut. |
magick rose: map_hourglass.png \
-fx 'p{ v.p{i*v.w/w,j*v.h/h}*w, j}' distort_hourglass.png
![[IM Output]](../static/img/mapping/distort_hourglass.png)
Bila diperhatikan baik-baik, koordinat X piksel 'i' dikalikan lebar gambar peta distorsi 'v.w', lalu dibagi lebar gambar asli 'w', menghasilkan 'i*v.w/w. Hal yang sama terjadi pada koordinat Y piksel, 'j*v.h/h'. Ini menskalakan ulang koordinat piksel pada gambar tujuan agar cocok dengan gambar LUT distorsi. Koordinat hasil pencarian kemudian diskalakan dengan mengalikan nilai LUT dengan lebar gambar sumber, menjadi koordinat X untuk pencarian warna. Bila Anda punya peta distorsi X sekaligus Y, pencarian berskala itu harus diulang untuk peta Y. Tentu saja kita masih punya distorsi 'tepi' yang sama seperti sebelumnya, jadi mari kita ubah Pengaturan piksel virtual menjadi transparansi. |
magick rose: -alpha set -virtual-pixel transparent -channel RGBA \
map_hourglass.png -fx 'p{ v.p{i*v.w/w,j*v.h/h}.g*w, j}' \
distort_hourglass2.png
![[IM Output]](../static/img/mapping/distort_hourglass2.png)
Perhatikan pemakaian pengaturan "-channel" untuk memastikan "-fx" bekerja dengan dan mengembalikan nilai kanal alpha (transparan) dari gambar sumber. Khususnya piksel virtual yang transparan. Perhatikan juga bahwa saat mencari pada peta distorsi kita hanya mencari dari kanal green (memakai 'v.p{}.g'). Bila ini tidak dilakukan, kanal yang sama dengan yang sedang diproses dari gambar sumber akan dipakai, padahal pada peta itu 'alpha' tidak terdefinisi. Peta distorsi ini bisa dibuat lebih baik lagi dengan memakai gradien non-linier sehingga gambarnya tetap persegi panjang, dengan distorsi lebih besar di tepi daripada di tengah, untuk memberi tampilan yang lebih 'membulat' atau 'silindris'. Ada yang mau mencoba? Email saya
Peta distorsi bola
Pada contoh Peta distorsi jam pasir sebelumnya, saya membuat gradien yang diskalakan secara horizontal oleh kurva kosinus. Dengan sedikit kerja tambahan, bentuk bola pun dapat dihasilkan... |
magick -size 100x100 xc: -channel R \
-fx 'yy=(j+.5)/h-.5; (i/w-.5)/(sqrt(1-4*yy^2))+.5' \
-separate +channel sphere_lut.png
![[IM Output]](../static/img/mapping/sphere_lut.png)
Namun perhatikan bahwa contoh di atas tidak sepenuhnya akurat. Gradien yang dimampatkan itu tetap gradien linier, hanya dimampatkan agar muat di dalam lingkaran. Representasi yang lebih akurat kemungkinan menuntut pembuatan gradien non-linier. Dalam istilah posisi absolut, itu berupa fungsi 'arccos()'. Nah, pemetaan ini juga punya beberapa area luas yang tergolong tidak sah, sehingga perlu semacam masking untuk mendefinisikan piksel mana yang sah dan tidak sah pada gambar akhir. Sebuah lingkaran sederhana sudah cukup untuk kasus ini. |
magick -size 100x100 xc:black -fill white \
-draw 'circle 49.5,49.5 49.5,0' sphere_mask.png
![[IM Output]](../static/img/mapping/sphere_mask.png)
Dan untuk melengkapinya kita juga butuh sorotan shading, seperti yang dikembangkan di Membuat highlight overlay, untuk dipakai oleh komposisi Overlay atau Hardlight... |
magick sphere_mask.png \
\( +clone -blur 0x20 -shade 110x21.7 -contrast-stretch 0% \
+sigmoidal-contrast 6x50% -fill grey50 -colorize 10% \) \
-composite sphere_overlay.png
![[IM Output]](../static/img/mapping/sphere_overlay.png)
Ingat bahwa shading di atas hanya berpengaruh di dalam batas objek bola, jadi kenyataan bahwa shading itu meluber keluar batas tersebut tidaklah penting. Sebenarnya, kalau Anda mau mencoba membuat shading bola yang lebih baik sehingga gambarnya makin menyerupai bola sungguhan, saya senang sekali melihatnya. Jadi mari kita terapkan ketiga gambar itu: LUT koordinat X, shading overlay, dan mask transparansi; pada gambar nyata berukuran tepat (demi kesederhanaan).
magick lena_orig.png -resize 100x100 sphere_lut.png -fx 'p{ v*w, j }' \
sphere_overlay.png -compose HardLight -composite \
sphere_mask.png -alpha off -compose CopyOpacity -composite \
sphere_lena.png
Contoh khusus ini memperlihatkan sisi paling kuat dari Peta distorsi absolut. Anda dapat mendefinisikan gradien pada objek bebas apa pun (tidak harus secara matematis), sehingga gambar apa pun dapat dipetakan ke objek itu, entah berupa lengkungan, kerutan, lipatan, dan sebagainya. Sederhananya, begitu pemetaan objeknya beres, gambar apa pun dapat dipetakan ke permukaannya. Lalu agar tampak lebih realistis, pemetaan kedua dapat di-overlay untuk menambahkan sorotan, bayangan, tepi, dan fitur lain. Tentu saja karena ketiga gambar itu grayscale, semuanya dapat digabungkan menjadi satu gambar Peta distorsi terpadu agar mudah disimpan. Dalam hal ini saya akan membuatnya lebih menyerupai distorsi bola dengan memakai ulang LUT distorsi koordinat X untuk koordinat Y juga. |
magick sphere_lut.png \( +clone -transpose \) \
sphere_overlay.png \( sphere_mask.png -negate \) \
-channel RGBA -combine spherical_unified.png
![[IM Output]](../static/img/mapping/spherical_unified.png)
Petanya memang cukup cantik. Tetapi bila hendak ditafsirkan, ingatlah bahwa: kanal 'red' dan 'green' adalah LUT koordinat X dan Y, 'blue' adalah overlay efek sorotan dan bayangan, dan kanal transparansi menyimpan mask piksel tidak sah untuk gambar akhir. Jadi mari kita terapkan memakai metode komposisi "Distort".
magick mandrill_grid_sm.jpg spherical_unified.png \
\( -clone 0,1 -alpha set -compose Distort -composite \) \
\( -clone 1 -channel B -separate +channel \) \
\( -clone 2,3 -compose HardLight -composite \) \
\( -clone 4,1 -compose DstIn -composite \) \
-delete 0--2 spherical_mandrill.png
Secara berurutan...
- kita terapkan peta distorsinya (yang sudah mencakup mask)
- ekstrak peta shading dari peta gambar terpadu
- terapkan peta shading itu pada gambar yang sudah didistorsi
- pulihkan mask yang hilang akibat operasi shading
- hapus semuanya kecuali gambar akhir lalu simpan
Kerumitan ini semata-mata karena mask shading perlu diekstrak, dan mask alpha yang dihapus shading perlu dipulihkan.
Peta distorsi busur lingkaran
Sekadar menunjukkan apa saja yang sebenarnya mungkin dilakukan dengan peta distorsi posisional, berikut sebuah LUT distorsi absolut yang serupa dengan yang disediakan 'Metode distorsi Arc' di atas. Pada dasarnya, alih-alih menghitung pemetaan koordinat untuk setiap piksel pada setiap gambar yang didistorsi, koordinat hasil hitungan itu kita simpan ke dalam dua peta LUT grayscale koordinat X dan Y. Artinya, kita menghitung seluruh distorsi di muka menjadi gambar look-up table yang lebih sederhana, sehingga ia dapat diterapkan berulang-ulang tanpa perlu akar kuadrat atau fungsi trigonometri lagi.
magick -pointsize 30 -font Candice label:Anthony -trim +repage \
-gravity center -resize 95x95 -crop 100x100+0+0\! \
-flatten text_image.jpg
magick -size 100x100 xc: -channel G -fx 'atan(j/(i+.5))*2/pi' \
-separate -flip -flop map_p_angle.png
magick -size 100x100 xc: -channel G -fx '1-hypot(i,j)/(w*1.6)' \
-separate -transverse map_p_radius.png
magick text_image.jpg map_p_angle.png map_p_radius.png \
-fx 'p{u[1]*w,u[2]*h}' distort_p_curved.jpg
Sumber warna |
|
Sudut - peta X |
|
Radius - peta Y |
|
Teks melengkung
Tentu saja membuat peta distorsi itu sulit, tetapi begitu selesai sekali, dengan cara apa pun yang Anda suka (bahkan secara artistik memakai penyunting gambar seperti "Gimp"), peta itu dapat dipakai ulang pada sejumlah besar gambar.
Peta distorsi polar
Kadang gambar tujuan perlu didefinisikan oleh peta distorsi, bukan oleh gambar sumber, semata agar semuanya bekerja dengan benar. Misalnya, bila kita ingin memetakan teks ke dalam lingkaran (dikenal juga sebagai transformasi polar), Anda benar-benar perlu memakai gambar yang panjangnya sekitar 3 sampai 4 kali tingginya (rasio aspek tinggi) atau hasilnya tidak akan terbaca. Untuk itu gambar peta distorsi kita letakkan sebelum gambar sumber warna, sehingga gambar pertama (peta X) yang dipakai menentukan ukuran hasil akhir, bukan gambar sumber masukan.
magick -size 100x100 xc: -channel G \
-fx 'atan2(i-w/2,h/2-j)/pi/2 + .5' \
-separate map_p_angular.png
magick -size 100x100 xc: -channel G \
-fx 'rr=hypot(i-w/2,j-h/2); (.5-rr/70)*1.2+.5' \
-separate map_p_radial.png
magick -font Candice -gravity center -size 200x50 \
label:'Around the World' text.jpg
magick map_p_angular.png map_p_radial.png text.jpg \
-fx 'u[2].p{ u*u[2].w, v*u[2].h }' distort_p_circle.jpg
Angular - peta X |
|
Radial - peta Y |
|
Sumber warna |
|
Teks melingkar
Pada dasarnya gambar sumber warna kini boleh berukuran atau berasio aspek berapa pun dan semuanya akan tertangani dengan benar, tetapi pembuatan peta distorsinya mungkin perlu disesuaikan agar rasio aspek gambar sumber tertangani dengan benar. Dalam pembuatan peta di atas, nilai '70' mengendalikan ukuran akhir lingkaran, tempat garis tengahnya diletakkan. Sedangkan nilai '1.2' mengendalikan penskalaan vertikal gambar ke dalam lingkaran, sehingga Anda dapat menyesuaikan tinggi teks yang didistorsi. |
Ingat, ekspresi "-fx" ini menuntut peta distorsi diberikan lebih dulu, dan sumber warna diberikan sebagai gambar ketiga (indeks 2). Namun ini juga berarti metadata apa pun yang tersimpan di gambar sumber akan hilang. |
|---|---|
| _Masalah pada peta distorsi ini adalah adanya diskontinuitas warna yang sangat tajam di 'peta X' (disebabkan asimtot dalam matematikanya). Garis ini harus tetap tajam ketika Anda melakukan pencarian warna atau mengubah ukuran peta untuk menghasilkan gambar yang lebih besar. Artinya, Anda perlu memastikan resize atau pencarian terinterpolasi apa pun atas peta ini tidak menghasilkan warna pencarian abu-abu di sepanjang garis asimtotik itu. |
Bila pencarian abu-abu memang muncul di sepanjang garis ini, hasil akhir Anda akan memuat sebaris piksel berwarna (yang diambil dari tengah gambar).
Karena itu disarankan peta distorsi ini selalu dibuat pada ukuran yang Anda butuhkan untuk gambar akhir, dan jangan sekali-kali memakai teknik penskalaan yang sudah ditunjukkan sebelumnya._
Ini dapat dipakai untuk efek lain juga, seperti papan catur melingkar... |
magick map_p_angular.png map_p_radial.png \
-size 150x90 pattern:checkerboard \
-fx 'u[2].p{ u*u[2].w, v*u[2].h }' distort_check_circle.gif
![[IM Output]](../static/img/mapping/distort_check_circle.gif)
Cobalah beberapa Pola bawaan lain yang disediakan IM dengan cara di atas untuk efek menarik lainnya. | _Contoh di atas dengan jelas memperlihatkan batas distorsi gambar memakai "-fx". Di dekat pusat gambar, garis-garis radialnya mulai mengalami aliasing karena penggabungan piksel dari area luas menjadi satu piksel tidak terjadi. Sebaliknya di tepi gambar, terutama di sudut-sudutnya, garis radial itu ter-blur secara wajar.
Penyebabnya, "-fx" (dan sebagian besar metode distorsi lama) hanya melakukan pencarian warna terinterpolasi sederhana tanpa penskalaan pada gambar sumber. Ini berarti ketika gambar diperkecil, piksel gambar sumber tidak digabungkan untuk menghasilkan warna yang benar bagi piksel tujuan.
Ini bukan masalah pada area pembesaran (seperti di sudut), hanya pada pemampatan ekstrem (pusat). Karena itu salah satu solusinya adalah memakai Super sampling, tetapi cara itu hanya menunda masalahnya sampai tingkat pemampatan yang lebih tinggi._
| _Garis asimtotik yang sama (perubahan mendadak) pada peta distorsi (dari pusat ke bagian bawah gambar) juga menghasilkan perubahan warna tajam di sepanjang garis itu pada contoh di atas. Bandingkan garis tersebut dengan garis radial lain (misalnya dari pusat ke bagian atas gambar) yang menjadi sangat kabur saat mendekati tepi gambar akibat pencarian terinterpolasi yang sudah disebut tadi.
Ini bisa menjadi masalah ketika membuat pola melingkar dengan gambar yang tileable (seperti di atas), dan mungkin menuntut penanganan khusus agar tidak ada perbedaan yang terlihat pada bagian gambar itu.
Untuk menghindarinya, mungkin lebih baik mendistorsi separuh bagian atas gambar terpisah dari separuh bagian bawahnya sehingga daerah asimtotik dapat dihindari.
Mengacak baris
Pada contoh ini kita melakukan sesuatu yang agak tidak biasa... mengacak baris-baris sebuah gambar. Pertama kita buat peta yang punya gradien untuk X (kanal red) dan gambar noise acak untuk Y (kanal green).
magick rose: \
\( -size 46x70 gradient: -rotate -90 \) \
\( -size 1x46 gradient: -spread 23 -scale 70x46\! \) \
-compose Distort -define compose:args='' -composite \
rose_row_shuffle.png
Sayangnya "-spread" tampaknya menyertakan piksel virtual dalam pemilihan piksel yang ditukar, sehingga sebagian baris menjadi kembar sementara sebagian lain hilang sama sekali. Dengan kata lain, peta gambar 'shuffle' ini belum sepenuhnya tepat. Punya solusi yang lebih baik untuk mengacak piksel?
Peta pencarian perpindahan relatif
Seperti Anda lihat, Peta distorsi absolut cukup mudah dibuat dan dipakai. Namun ia punya masalah serius ketika sebuah distorsi memiliki daerah 'tak terdefinisi', atau area tempat distorsi keluar dari batas normal gambar sumber. Masalah yang lebih serius: Anda selalu berurusan dengan gradien, yang mendefinisikan koordinat absolut untuk pencarian warna. Tidak ada bagian dari gambar pemetaan itu yang sederhana, bersih, atau mudah dimodifikasi maupun disunting dengan tangan. Pembuatan dan pemakaiannya menuntut teknik dan matematika khusus. Umumnya itu berarti nyaris tidak ada ruang bagi pengembangan yang 'artistik'. Namun ada metode lain untuk memakai Lookup Table guna menentukan koordinat tempat warna akhir diambil, yaitu dengan peta perpindahan relatif. Alih-alih 'peta' itu mendefinisikan koordinat persis tempat warna setiap piksel dicari pada gambar sumber, ia mendefinisikan offset atau perpindahan relatif terhadap posisi saat ini. Nah, sebuah offset bisa bernilai positif atau negatif, dan nilai negatif menuntut sedikit akal-akalan untuk dikodekan ke dalam nilai warna. Jadi yang dilakukan adalah mendefinisikan 'abu-abu murni' sebagai perpindahan koordinat 0 (tanpa perubahan). Lalu 'hitam' berarti perpindahan negatif maksimum, dan 'putih' berarti perpindahan positif maksimum. Ini sulit diuraikan dengan kata-kata, jadi mari kita lihat sebuah contoh. Pertama kita buat gambar uji untuk 'dipindahkan'. |
magick -font Candice -gravity center -size 150x50 \
label:'Anthony' label.jpg
![[IM Output]](../static/img/mapping/label.jpg)
Sekarang saya akan memakai sedikit 'magick' untuk membuat gambar 'abu-abu murni' dengan area 'putih murni' dan 'hitam murni'. |
echo "P2 5 1 255\n 127 0 127 255 127" |\
magick - -scale 150x50\! -alpha off displace_map.jpg
![[IM Output]](../static/img/mapping/displace_map.jpg)
Untuk memakai gambar ini sebagai 'peta perpindahan', kita ambil 'nilai abu-abu' dari peta perpindahan itu, lalu menambahkannya ke koordinat X dan/atau Y. Artinya kita menggeser pencarian sejauh jarak relatif dari posisi saat ini menurut tingkat 'keabuan' peta perpindahan. 'Nilai' itu ditangani secara khusus, sehingga 'abu-abu murni' berarti perpindahan nol pada titik pencarian (dalam hal ini hanya koordinat Y), sementara 'perpindahan maksimum' dipakai untuk nilai 'putih' (positif) atau 'hitam' (negatif). Misalnya, mari kita terapkan peta perpindahan itu pada gambar "label" kita. |
magick label.jpg displace_map.jpg -virtual-pixel Gray \
-fx 'dy=10*(2*v-1); p{i,j+dy}' displaced.jpg
![[IM Output]](../static/img/mapping/displaced.jpg)
Seperti Anda lihat, berbagai bagian gambar tampak 'bergerak' sesuai warna peta perpindahan. Daerah 'putih' akan menambahkan 'nilai perpindahan' yang diberikan ke titik pencarian, sehingga di area itu setiap piksel mencari gambar sumber '10' piksel ke 'selatan' (arah Y positif). Akibatnya gambar tampak bergerak ke atas. Ingat, yang dipindahkan adalah pencariannya, BUKAN gambarnya sendiri, dan itulah sebabnya gambar tampak bergerak ke atas atau ke arah negatif untuk warna putih. Efek serupa juga terlihat pada area dengan perpindahan 'hitam'. Gambar sumber tampak bergerak ke bawah, karena perpindahan pencariannya dilakukan ke arah negatif. Pikirkan baik-baik. Anda juga akan memperhatikan bahwa 'pencarian yang dipindahkan' itu sebenarnya bisa melihat melampaui batas normal gambar, sehingga pengaturan Piksel virtual dapat dipakai untuk mengendalikan piksel di luar batas tersebut. Pada contoh di atas saya sekadar meminta agar piksel abu-abu yang dikembalikan. Nilai 'perpindahan maksimum' '10' pada contoh di atas sangat penting, dan merupakan jarak relatif terjauh yang tampak ditempuh bagian mana pun dari gambar sumber, untuk nilai perpindahan 'putih murni' atau 'hitam murni' pada gambar pemetaan. Pencarian, dan dengan demikian gambar masukan, tidak dapat dipindahkan lebih jauh dari nilai itu. Rona abu-abu lain di antara nilai maksimum putih atau hitam dan nilai abu-abu 50% tanpa perpindahan akan memindahkan pencarian sejauh nilai yang sepadan. Jadi nilai abu-abu 25% akan memindahkan pencarian sejauh 1/2 nilai perpindahan ke arah negatif, sedangkan abu-abu 75% memindahkannya sejauh 1/2 nilai itu ke arah positif. Nilai inilah perbedaan kunci antara Peta distorsi absolut dan Peta perpindahan relatif. Perpindahan relatif dapat diperbesar atau diperkecil, sehingga gambar menjadi lebih atau kurang terdistorsi, hanya dengan mengubah nilai perpindahannya, tanpa perlu mengubah peta perpindahannya sama sekali. Selain itu, karena peta 'perpindahan nol' hanyalah abu-abu 50% polos, bukan gradien rumit, Anda dapat mulai dari gambar abu-abu sederhana lalu secara artistik menerangkan atau menggelapkan sebagian area untuk menghasilkan perpindahan yang diinginkan. Itu dapat dilakukan sekadar dengan menggambar bentuk atau area, bukan dengan rumus matematis yang rumit dan persis. Dan akhirnya, karena semua perpindahan bersifat relatif, nilai liar seperti yang dihasilkan efek tepi tidak menghasilkan warna piksel yang liar atau acak. Nyatanya, seperti akan Anda lihat, menghaluskan atau mem-blur Peta perpindahan justru bagus karena menghilangkan efek 'terpotong' atau tidak menyambung yang terlihat pada contoh di atas. Ringkasnya peta perpindahan jauh lebih terkendali dan artistik, memberikan perpindahan setempat tanpa perlu matematika yang rumit dan persis, serta sangat pemaaf terhadap kesalahan, efek tepi, bahkan blur pada peta perpindahannya. Ia ideal untuk distorsi bertipe 'perpindahan' sederhana seperti saat membuat efek air, gelombang, cermin yang membengkokkan bayangan, pembelokan cahaya, efek mirip lensa, atau efek kaca buram maupun bergelembung. Sebaliknya, distorsi yang sangat matematis seperti distorsi 'polar', rotasional, dan 'perspektif', atau pemetaan tiga dimensi dunia nyata lainnya, tidak mudah dicapai. Bukan berarti mustahil, karena nanti akan ditunjukkan bahwa kedua gaya peta itu sebenarnya dapat dikonversi satu sama lain, hanya saja lebih sulit.
Metode komposisi Displace
Kita memakai Operator DIY FX untuk melakukan pemetaan perpindahan, supaya terlihat apa yang sebenarnya dikerjakan. Tetapi teknik itu lambat. Namun ada Operator komposisi bawaan yang setara, yaitu "Displace". Beginilah cara memakainya...
magick {_image_} {_displacement_map_} \
-compose Displace -define compose:args={_X_}x{_Y_} \
-composite {_result_ +}
magick {_image_} {_displacement_map_} \
-compose Displace -set option:compose:args {_X_}x{_Y_} \
-composite {_result_ +}
magick composite {_displacement_map_} {_image_} \
-displace {_X_}x{_Y_} {_result_ +}
Perhatikan urutannya, terutama pada perintah "magick composite".
Pemakaian "-set" alih-alih define juga memungkinkan pemakaian Percent escape di dalam argumennya. Nilai 'X ' dan 'Y ' mendefinisikan arah dan 'perpindahan maksimum' yang dipakai untuk warna 'putih' dan 'hitam' pada peta perpindahan yang diberikan. Salah satu atau kedua nilai itu dapat didefinisikan, sehingga perpindahan dapat dilakukan ke arah mana pun. Artinya, peta perpindahan biasanya memberikan perpindahan linier ke suatu arah bebas dengan intensitas maksimum yang dikendalikan nilai 'X ' dan 'Y '. 'Gambar peta' lalu menentukan seberapa besar dari maksimum itu yang diterapkan, dari maksimum negatif (hitam) sampai maksimum positif (putih), dengan abu-abu sempurna berarti tidak ada perpindahan pencarian untuk piksel tersebut. Misalnya, berikut contoh perpindahan Y yang sama seperti di atas... |
magick label.jpg displace_map.jpg -virtual-pixel Gray \
-compose Displace -define compose:args=0x10 -composite \
displaced_y.jpg
![[IM Output]](../static/img/mapping/displaced_y.jpg)
Pengaturan lain seperti "-geometry" dan "-gravity" juga dapat dipakai untuk menyesuaikan area tempat peta perpindahan di-overlay pada gambar. Pencarian piksel yang dihasilkan peta perpindahan tetap dapat merujuk ke area di luar bagian gambar yang di-overlay itu, lalu menggandakannya ke dalam area overlay tersebut.
Contoh perpindahan sederhana
Peta perpindahan yang berisi blok-blok warna polos tanpa transisi halus umumnya menghasilkan perpindahan yang tidak menyambung (diskontinu) antar-area pada gambar hasil, persis seperti yang Anda lihat di atas. Nyatanya teknik ini dapat dipakai untuk membuat peta perpindahan yang 'meretak' seolah Anda memandang ke cermin yang pecah. Lihat misalnya Cermin retak di bawah. Hasil yang lebih enak dilihat dan lebih halus dapat diperoleh bila warnanya mengalir mulus dari satu area ke area lain. Misalnya, dengan mem-blur peta perpindahan, transisi mirip gelombang akan muncul di antara area yang dipindahkan... |
magick displace_map.jpg -blur 0x10 dismap_wave.jpg
magick label.jpg dismap_wave.jpg -virtual-pixel Gray \
-compose Displace -define compose:args=0x10 -composite \
displaced_wave_y.jpg
![[IM Output]](../static/img/mapping/dismap_wave.jpg)
![[IM Output]](../static/img/mapping/displaced_wave_y.jpg)
Alih-alih memindahkan gambar ke arah Y, sebuah peta juga dapat dipakai untuk memindahkan gambar ke arah X sehingga menghasilkan semacam gelombang mampat. |
magick label.jpg dismap_wave.jpg -virtual-pixel Gray \
-compose Displace -define compose:args=10x0 -composite \
displaced_wave_x.jpg
![[IM Output]](../static/img/mapping/displaced_wave_x.jpg)
Dengan memakai peta perpindahan yang sama untuk arah X dan Y, kita dapat menambahkan gelombang mampat sekaligus gelombang amplitudo. |
magick label.jpg dismap_wave.jpg -virtual-pixel Gray \
-compose Displace -define compose:args=10x10 -composite \
displaced_wave_xy.jpg
![[IM Output]](../static/img/mapping/displaced_wave_xy.jpg)
Perhatikan bahwa gambarnya tetap dipindahkan ke satu arah linier, sehingga gambar di atas teregang pada lereng menurun dan tergencet pada lereng menanjak. Artinya, distorsinya dilakukan pada suatu sudut atau 'vektor', dengan komponen horizontal sekaligus vertikal. Terlihat bahwa efek ini luar biasa mirip pemandangan di bawah air, dengan gambar yang terdistorsi oleh riak lembut di permukaan air. Namun sebuah peta distorsi dapat memuat beberapa salinan gambar asli, sama seperti pada gambar yang dipantulkan atau dibiaskan... |
echo "P2 3 1 255\n 255 127 0 " | magick - -scale 150x50\! dismap_copy.jpg
magick label.jpg dismap_copy.jpg \
-compose Displace -define compose:args=66x0 -composite \
displaced_copy.jpg
![[IM Output]](../static/img/mapping/dismap_copy.jpg)
![[IM Output]](../static/img/mapping/displaced_copy.jpg)
Anda juga dapat membuat bagian gambar di-flip atau di-flop seperti cermin dengan memakai gradien. Misalnya, di sini peta perpindahan linier dipakai untuk menyalin piksel dari satu sisi gambar ke sisi lainnya. |
magick -size 50x150 gradient: -rotate -90 -alpha off dismap_mirror.png
magick label.jpg dismap_mirror.png \
-compose Displace -define compose:args=150x0 -composite \
displaced_mirror.jpg
![[IM Output]](../static/img/mapping/dismap_mirror.png)
![[IM Output]](../static/img/mapping/displaced_mirror.jpg)
Bisa menebak cara kerja peta perpindahan ini? Sebagai petunjuk, cari tahu berapa perpindahan pada tepi paling kiri dan paling kanan, lalu lihat bagaimana sisa gambarnya menyesuaikan diri. Namun karena Anda lagi-lagi memakai gambar gradien, kesederhanaan peta perpindahan pun hilang. Karena itu efek cermin lebih baik dikerjakan dengan Operasi flip langsung pada gambar, atau dengan Peta distorsi absolut. Perhatikan bahwa dengan membalik gradiennya, gambar justru mengecil. |
magick -size 50x150 gradient: -rotate 90 -alpha off dismap_shrink.png
magick label.jpg dismap_shrink.png \
-compose Displace -define compose:args=150x0 -composite \
displaced_shrink.jpg
![[IM Output]](../static/img/mapping/dismap_shrink.png)
![[IM Output]](../static/img/mapping/displaced_shrink.jpg)
Contoh di atas juga memperlihatkan satu masalah khas peta perpindahan. Ketika sebuah area (atau seluruh) gambar dimampatkan lebih dari 50%, Artefak aliasing mulai muncul. Ini terutama tampak pada tepi bertangga yang jelas ber-alias. Seperti sudah dibahas, salah satu solusinya adalah Super sampling, yaitu menambah jumlah piksel yang dipakai untuk menghasilkan tiap piksel keluaran. Untuk itu kita perbesar gambar sekaligus peta perpindahannya, lalu kembalikan ukuran gambar hasilnya ke ukuran normal. Dengan begitu lebih banyak piksel ikut menentukan sebuah piksel pada hasilnya, sehingga gambarnya lebih baik. Misalnya... |
magick label.jpg dismap_shrink.png -resize 200% \
-compose Displace -define compose:args=400x0 -composite \
-resize 50% displaced_resize.jpg
![[IM Output]](../static/img/mapping/displaced_resized.jpg)
Hasilnya jauh lebih baik dan lebih halus, meski mungkin sedikit kabur. Menggambar grafik sebuah gradien Langsung dari contoh di atas muncul gagasan bahwa dengan memakai perpindahan Y atas sebuah garis sederhana, grafik warna sebuah peta perpindahan dapat dihasilkan. Misalnya, di sini saya membuat fungsi matematis sinc() (yang didefinisikan sebagai 'sin(x)/x'), lalu menggambar grafik gradien itu dengan memakainya sebagai peta perpindahan...
magick -size 121x100 xc: -fx 'sin(i*24/w-12)/(i*24/w-12)/1.3+.2' \
gradient_sinc.gif
magick -size 121x100 xc: -draw 'line 0,50 120,50' graph_source.gif
magick graph_source.gif gradient_sinc.gif \
-compose Displace -define compose:args=0x49 -composite \
displace_graph.gif
Seperti Anda lihat, cara ini berhasil, meski saya sendiri enggan memakainya untuk plot matematis. Lebih baik memakai paket penggambar grafik yang benar. Namun teknik ini berguna sebagai cara cepat dan kasar untuk memplot intensitas sebaris atau sekolom piksel pada sebuah gambar. Yang ditunjukkannya adalah bagaimana perbedaan perpindahan yang besar dapat dengan mudah menghasilkan diskontinuitas atau hasil yang tidak halus. Pada dasarnya, karena tiap piksel pada "sumber grafik" hanya dilihat satu per satu tanpa perataan, perbedaan besar pada pencarian yang dipindahkan dari satu piksel ke piksel berikutnya dapat menghasilkan perubahan warna yang besar pada hasilnya. Pelajarannya, perpindahan bekerja paling baik bukan hanya dengan peta perpindahan yang halus, tetapi juga dengan gambar yang memuat area luas atau gradasi warna. Ia tidak begitu cocok untuk garis tipis yang tajam. Tentu saja hasilnya dapat diperbaiki lagi dengan Super sampling peta distorsinya... |
magick graph_source.gif gradient_sinc.gif -resize 400% \
-compose Displace -define compose:args=0x196 -composite \
-resize 25% displace_graph_2.gif
![[IM Output]](../static/img/mapping/displace_graph_2.gif)
Hasilnya jauh lebih baik, meski belum sebaik yang dapat dicapai dengan paket penggambar grafik. Tetap saja, hanya ImageMagick yang dipakai untuk membuatnya. Berikut versi lain dari grafik yang sama, tetapi kali ini memakai warna polos, yang jauh lebih baik hasilnya daripada memindahkan garis tipis. |
magick -size 121x50 xc:white xc:black -append \
gradient_sinc.gif -resize 400% \
-compose Displace -define compose:args=0x196 -composite \
-resize 25% displace_graph_3.gif
Perpindahan area (linear)
Mari kita coba persoalan perpindahan yang lebih masuk akal, yaitu memindahkan sebuah area gambar dalam garis lurus dari satu lokasi ke lokasi lain. Seperti sudah kita lihat, gambar 'abu-abu murni' tidak menyebabkan perpindahan apa pun, sedangkan warna 'putih' menyebabkan perpindahan pencarian positif dari gambar sumber. Misalnya, mari kita buat gambar semacam itu.... |
magick -size 75x75 xc:gray50 -fill white \
-draw 'circle 37,37 37,20' dismap_spot.jpg
![[IM Output]](../static/img/mapping/dismap_spot.jpg)
Sekarang ketika gambar ini diterapkan, isi area yang ditandai seharusnya memuat salinan dari apa pun yang muncul pada arah nilai perpindahan yang diberikan. Jadi mari kita coba nilai perpindahan X +10 dan Y +10 atau '10x10'...
magick koala.gif dismap_spot.jpg \
-compose Displace -define compose:args=10x10 -composite \
displace_spot.png
Seperti Anda lihat, isi area yang ditandai kini memuat salinan gambar yang berada +10,+10 piksel ke arah tenggara. Pada dasarnya gambar 'ekor' koala. Dengan kata lain, di dalam lingkaran itu gambarnya dipindahkan ke timur laut, atau -10,-10 piksel. Ingat, yang dipindahkan adalah pencariannya, jadi gambar sumber bergeser sejauh nilai negatif karena Pemetaan piksel terbalik. Gambarnya berpindah ke arah sebaliknya! Perhatikan juga bahwa yang berpindah adalah gambar di dalam area yang ditandai. Anda tidak memindahkan gambar yang ditandai, melainkan memindahkan gambar KE DALAM area yang ditandai. Dan terakhir, perhatikan diskontinuitas tajam di tepi lingkaran. Area di dalam tanda ikut berpindah, sedangkan area di luarnya tetap persis seperti semula. Ini fakta, jadi layak diulang.
Perpindahan menggerakkan gambar ke arah berlawanan dengan nilainya.
Hanya area yang ditandai bukan abu-abu yang akan dipindahkan.
Perubahan warna yang tajam menghasilkan diskontinuitas gambar yang tajam.
Jadi mari kita coba sesuatu yang lebih praktis. Mari kita pindahkan titik tengah antara hidung dan mata koala, yang berada di '32,22', ke pusat lingkaran putih kita (perpindahan positif penuh) di '37,37'. Itu membutuhkan nilai perpindahan '-5,-15' (ingat, arahnya terbalik)... |
magick koala.gif dismap_spot.jpg \
-compose Displace -define compose:args=-5x-15 -composite \
displace_head.png
![[IM Output]](../static/img/mapping/displace_head.png)
Dan di sana kita punya salinan bagian tengah kepala koala yang terpusat rapi. Tetapi gambarnya masih 'terputus', dan memakai nilai negatif juga kurang enak. Solusinya adalah memakai bercak hitam, sekaligus mem-blur tepi bercak itu. Mari kita buat juga bercaknya lebih besar agar mencakup lebih banyak bagian kepala koala. Jadi inilah gambar 'bercak gerak positif' kita... |
magick -size 75x75 xc:gray50 -fill black \
-draw 'circle 37,37 37,17' -blur 0x5 dismap_area.jpg
![[IM Output]](../static/img/mapping/dismap_area.jpg)
Jangan mem-blur gambarnya terlalu banyak atau bagian tengah bercak tidak lagi berwarna hitam rata. Sebagai alternatif, Anda bisa saja melakukan Normalize dan Penyesuaian level terbalik pada gambar itu untuk memastikan area yang digambar berwarna hitam dan bagian sekitarnya abu-abu sempurna. Cara ini akan sering terlihat pada contoh-contoh berikutnya. Sekarang mari kita ulangi perpindahan 'kepala' tadi memakai peta perpindahan 'bercak kabur' hitam kita. |
magick koala.gif dismap_area.jpg \
-compose Displace -define compose:args=5x15 -composite \
displace_area.png
![[IM Output]](../static/img/mapping/displace_area.png)
Seperti Anda lihat, kita memindahkan gambar sejauh +5,+15 ke dalam area 'kabur' itu, tetapi kali ini batas areanya lebih halus dan menyatu dengan sisa gambar. Tentu saja telinga di tepi lingkaran ikut terdistorsi oleh tepi yang kabur, dan badan koala pun ikut memampat, tetapi hasilnya masih jauh lebih baik daripada sebelumnya. Untuk mencegah 'robekan' gambar yang terlihat di sisi belakang, atau tertinggalnya salinan bagian yang dipindahkan, bercak itu perlu diperluas, atau dibuat gambar perpindahan bertipe gradien yang lebih rumit. Misalnya, umpamakan Anda ingin memindahkan kepala koala dari posisi awalnya di '32,22' ke pusat gambar di '37,37', atau gerakan sejauh +5,+15 piksel, tetapi Anda ingin seluruh gambar menyesuaikan diri dengan perubahan itu agar efeknya jauh lebih halus. Untuk itu Anda memerlukan perpindahan maksimum warna hitam (perpindahan gambar positif) di '37,37' dengan nilai +5,+15, tetapi juga perlu memastikan sisa gambarnya tetap utuh dengan 'memaku' sudut-sudutnya pada abu-abu 50%. Itu persis cocok untuk Gradien jarang terinterpolasi Shepard.
magick -size 75x75 xc: -sparse-color Shepards \
'37,37 black 0,0 gray50 74,74 gray50 0,74 gray50 74,0 gray50' \
dismap_move.jpg
magick koala.gif dismap_move.jpg \
-compose Displace -define compose:args=5x15 -composite \
displace_move.png
Seperti Anda lihat, sebaran perpindahannya kini menyebar ke seluruh gambar. Hasilnya adalah gambar yang berubah jauh lebih mulus dibanding metode 'bercak' yang lebih sempit tadi. Ini sebenarnya persis setara dengan Distorsi Shepard, hanya saja untuk satu titik kendali yang bergerak. Ini juga persis metode yang dipakai skrip 'shapemorph' karya Fred Weinhaus, dengan tambahan animasi. Ringkasnya: untuk perpindahan setempat yang kecil, perpindahan 'bercak ter-blur' dapat dipakai. Tetapi untuk perpindahan yang lebih besar dan berjarak lebih jauh, sebaiknya dipakai peta perpindahan bergradien halus yang lebih luas agar gambar sumber tidak robek atau tergandakan.
Sedang dikerjakan
Morphing perpindahan sederhana
Mengubah ukuran vektor perpindahan
Morphing dua gambar
Perpindahan 1D acak
Pantulan air beriak
Seperti sudah disebut, peta perpindahan sangat berguna untuk membuat distorsi mirip air dan kaca.
Untuk contoh ini saya membuat gambar kecil dengan Memangkas sebuah gambar bunga. Sekarang saya ingin membuatnya tampak berada di atas air yang beriak. Untuk menghasilkan riak, saya perlu gradien gelombang sinus berukuran sama, yang dapat dibuat memakai Fungsi Evaluate Sin. Angka '8' menyatakan jumlah 'gelombang' yang akan ditambahkan ke gradien itu. |
magick -size 150x80 gradient: -evaluate sin 8 wave_gradient.png
![[IM Output]](../static/img/mapping/wave_gradient.png)
Sekarang mari kita distorsi gambar itu memakai vektor perpindahan bersudut, bukan sekadar distorsi vertikal atau horizontal, agar efeknya lebih terasa. |
magick composite wave_gradient.png flower.jpg -displace 5x5 flower_waves.png
![[IM Output]](../static/img/mapping/flower_waves.png)
Sekilas itu tampak tidak menarik, tetapi bagaimana bila gambar itu di-flip, dimampatkan secara vertikal, lalu disambungkan ke gambar aslinya... |
magick flower_waves.png -flip \
flower.jpg +swap -append flower_waves_2.png
![[IM Output]](../static/img/mapping/flower_waves_2.png)
Sayangnya hasilnya masih tampak buatan. Alasannya, pantulan itu tampak sama di bagian atas maupun bawah gambar. Tidak ada kesan 'kedalaman'. Kecerlangan pantulannya juga sama dengan gambar aslinya, padahal itu jarang terjadi. Agar lebih realistis, diperlukan pola riak yang intensitasnya bervariasi. Contoh berikut memakai Matematika gradien yang canggih untuk 'meredam' gradien gelombang yang tadi kita pakai. Artinya, pola gelombangnya kita buat mengecil secara linier dari atas ke bawah. Akal-akalan ini memastikan gelombangnya berakhir pada warna abu-abu murni atau 'tanpa perpindahan' di bagian bawah gambar (yang nanti di-flip). |
magick -size 150x80 gradient: \
\( wave_gradient.png \
+clone -compose multiply -composite \) \
\( -clone 0 -negate -evaluate divide 2 \
-clone 1 -compose plus -composite \) \
-delete 0-1 waves_decreasing.png
![[IM Output]](../static/img/mapping/waves_decreasing.png)
Jadi mari kita terapkan gradien ini untuk membentuk pantulan bunga yang baru. Saya juga sedikit menggelapkan gambar pantulannya untuk mewakili sebagian cahaya yang hilang ke dalam air, sehingga lebih terasa seperti pantulan di air. |
magick flower.jpg waves_decreasing.png \
-compose Displace -define compose:args=8x8 -composite \
-flip +level 0,80% \
flower.jpg +swap -append flower_in_water.png
![[IM Output]](../static/img/mapping/flower_in_water.png)
Perhatikan bahwa gambar yang didistorsi itu Di-flip untuk membentuk pantulan. Gambarnya juga akan punya lebih sedikit 'riak' di bagian atas 'air', yaitu yang paling dekat dengan sambungan ke gambar asli, dibanding di bagian bawah. Ini memberi distorsi itu kesan jarak dari pengamat. Hasilnya dapat dibuat lebih realistis lagi dengan mendistorsi peta perpindahan gelombangnya memakai sedikit rotasi, busur, atau sekadar perpindahan 'acak'. Ini akan membuat gelombangnya tampak lebih alami. Meski lebih baik dikerjakan sebelum gelombang itu 'diredam', supaya 'kedalaman' ditambahkan sesudahnya. Cobalah, bereksperimenlah, dan beri tahu saya apa yang Anda temukan.
Future Animated Ripples -
Using -function Sinusoid with phase changing
Pemetaan perpindahan 2 dimensi
Sejauh ini semua peta perpindahan relatif hanya memindahkan gambar ke satu arah saja. Meski arah itu dapat disetel ke sudut mana pun dengan menetapkan nilai atau 'vektor' perpindahan '_X_ x _Y_' yang sesuai. Namun perpindahan yang jauh lebih rumit dapat dihasilkan, dengan gambar dipindahkan ke arah mana pun sejauh berapa pun, memakai dua perpindahan terpisah. Untuk itu kita perlu membuat dua peta perpindahan, satu untuk arah X dan satu untuk arah Y. Berikut perintah yang dapat dipakai...
magick {_image_} {_X displacement_} {_Y displacement_} \
-compose Displace -define compose:args={_X_}x{_Y_} \
-composite {_result_ +}
magick {_image_} {_X displacement_} {_Y displacement_} \
-compose Displace -set option:compose:args {_X_}x{_Y_} \
-composite {_result_ +}
composite {_X displacement_} {_image_} {_Y displacement_} \
-displace {_X_}x{_Y_} {_result_ +}
Perhatikan urutan gambar masukan pada perintah "magick composite". Urutan yang aneh itu disebabkan keharusan menyiasati penanganan opsi "magick composite", dan juga alasan historis. Urutan ini wajib benar. Karena itu saya menyarankan pemakaian perintah "magick", bukan "magick composite". |
Sebelum IM v6.4.4, memakai 2 peta perpindahan terpisah untuk perpindahan X dan Y adalah untung-untungan. Kadang berhasil, kadang tidak. Jangan coba memakainya pada IM yang lebih lama dari versi tersebut. |
|---|---|
| Selain itu, seperti pada Peta distorsi terpadu, satu "peta perpindahan terpadu" juga dapat dipakai. Bila hanya satu gambar perpindahan yang diberikan, perpindahan X akan diambil dari kanal 'red', perpindahan Y dari kanal 'green', dan mask alpha apa pun juga akan dipindahkan dari peta perpindahan ke gambar akhir. Kanal 'blue' diabaikan. | _Secara internal, baik "magick" maupun "magick composite' sebenarnya menggabungkan kedua gambar itu (bila diberikan) untuk menghasilkan 'peta perpindahan terpadu', sebelum meneruskannya ke API internal. |
Ini tidak memengaruhi 'perpindahan linier' yang kita lihat sebelumnya, karena peta perpindahan yang diberikan saat itu berupa gambar grayscale, sehingga kanal 'red' dan 'green' identik._
Perpindahan silindris
Sesuatu yang berkali-kali muncul di forum IM adalah cara memetakan gambar ke sebuah silinder, misalnya untuk di-overlay pada cangkir kopi atau kaleng minuman. Inilah solusinya... |
magick rose: -background black -gravity south -splice 0x8 \
\( +clone -sparse-color barycentric '0,0 black 69,0 white' \) \
\( -clone 1 -function arcsin 0.5 \) \
\( -clone 1 -level 25%,75% \
-function polynomial -4,4,0 -gamma 2 \
+level 50%,0 \) \
-delete 1 \
-virtual-pixel black -define compose:args=17x7 \
-compose Displace -composite rose_cylinder.png
![[IM Output]](../static/img/mapping/rose_cylinder.png)
Perintah di atas sangat rumit, tetapi pada intinya memakai dua perpindahan sekaligus. Pemampatan arcsin() pada arah X, dan perpindahan busur lingkaran pada arah Y. Beginilah yang dikerjakan perintah itu...
- Muat gambar "rose" dan tambahkan ruang untuk perpindahan vertikal
- Buat gradien matematis horizontal untuk fungsi matematis berikutnya
- Olah satu salinan gradien itu menjadi peta perpindahan yang memampatkan
- Olah salinan lain menjadi perpindahan busur eliptis vertikal
- Hapus gradien liniernya
- Siapkan lalu jalankan perpindahannya
Hasilnya... sekuntum mawar yang terbungkus dengan benar ke tampilan isometrik 30 derajat sebuah silinder. Pecah perintah di atas untuk menyimpan dan melihat masing-masing peta perpindahannya. Kuncinya, ingat bahwa perpindahan dua peta itu melakukan pencarian nilai X sekaligus Y, untuk menentukan piksel mana yang akan berakhir di lokasi pencarian tersebut. Ingat, perpindahan itu sebenarnya bukan perpindahan gambar sumber, melainkan perpindahan pencarian ke dalam gambar sumber. Metode distorsi perpindahan ini sudah ditanamkan ke dalam skrip "cylinderize" karya Fred Wienhaus.
Cermin retak
Tampilan 'cermin retak' dapat dibuat pada sebuah gambar dengan menghasilkan area perpindahan X dan Y secara acak.
magick dragon_sm.gif -sparse-color voronoi ' \
%[fx:rand()*w],%[fx:rand()*h] red
%[fx:rand()*w],%[fx:rand()*h] lime
%[fx:rand()*w],%[fx:rand()*h] black
%[fx:rand()*w],%[fx:rand()*h] yellow
' -interpolate integer -implode 1 mirror_areas.gif
magick mirror_areas.gif -channel R -separate mirror_dismap_x.gif
magick mirror_areas.gif -channel G -separate mirror_dismap_y.gif
magick composite mirror_dismap_x.gif dragon_sm.gif mirror_dismap_y.gif -alpha off \
-background white -virtual-pixel background -displace 7 \
mirror_displaced.gif
magick mirror_areas.gif -edge 1 -threshold 20% \
-evaluate multiply .7 -negate mirror_cracks.gif
magick composite mirror_displaced.gif mirror_cracks.gif -compose multiply \
mirror_cracked.gif
| Empat area yang dipindahkan secara acak dihasilkan memakai gambar Voronoi Sparse Color yang diacak. Gambar itu lalu diberi Distorsi Implode untuk melengkungkan area tersebut ke pusat gambar. Karena masing-masing dari keempat area berwarna itu tetap berwarna polos, tiap area akan memuat salinan gambar asli yang tidak terdistorsi namun berpindah. Namun tiap area memindahkan gambar dengan cara berbeda, persis seperti tiap serpihan cermin yang retak. Untuk merampungkan cerminnya, Deteksi tepi dipakai untuk menggarisi tepi tiap wilayah sehingga sifat retak gambar hasilnya terlihat. Artinya, retakannya pun dibuat kasatmata. | Secara teknis saya tidak harus memisahkan kanal 'red' dan 'green' pada peta perpindahan acak berwarna yang dihasilkan itu. Saya bisa saja memakainya langsung, karena perpindahan X diambil dari kanal 'red' dan perpindahan Y dari kanal 'green'. Artinya, saya bisa memakai gambar "mirror_areas.gif" langsung sebagai "peta perpindahan terpadu". |
|---|---|
Sedang dikerjakan
Perpindahan Shepards
Perpindahan acak
Efek lensa
Efek kaca buram
Efek dispersi (perpindahan diputar)
Efek dispersi dengan perpindahan teracak
FUTURE: Other possible distort / displace mapping examples
- Raytrace a gradient onto 3D objects so that later ANY image can be be mapped onto those objects.
- X and Y gradient mapped images
- Pure Gray Image for color, highlights and shading
Pemetaan blur variabel
Ditambahkan pada ImageMagick versi 6.5.4-0, metode 'Blur' dari "-compose" menyediakan cara mengganti tiap piksel dengan rata-rata Gaussian eliptis (sebuah blur) dari piksel tetangganya, menurut sebuah gambar pemetaan.
magick composite -blur {_Xscale_}[x{_Yscale_}[+{_angle_}]] blur_map image result
magick image blur_map \
-define compose:args='{_Xscale_}[x{_Yscale_}[+{_angle_}]]' \
-compose blur -composite result
magick image blur_map \
-set option:compose:args '{_Xscale_}[x{_Yscale_}[+{_angle_}]]' \
-compose blur -composite result
Perhatikan bahwa Komposisi gambar ini menuntut argumen operasional, yang dapat disetel dengan sejumlah cara. Lihat Artifact yang didefinisikan global untuk rinciannya. Dengan memakai peta variabel untuk mengendalikan blur, satu bagian gambar dapat di-blur sementara bagian lain dibiarkan utuh, atau efek seperti Efek tilt-shift dapat dihasilkan, tempat gambar dunia nyata dibuat tampak lebih seperti model buatan berukuran kecil.
Misalnya, di sini saya mem-blur separuh gambar koala sementara separuh lainnya sama sekali tidak di-blur...
magick -size 37x75 xc:black -size 38x75 xc:white +append blur_map_bool.gif
magick koala.gif blur_map_bool.gif \
-compose blur -define compose:args=3 -composite \
blur_koala_bool.gif
Seperti Anda lihat, setiap piksel yang 'putih' pada gambar 'blur_map' di-blur memakai nilai sigma maksimum yang diberikan, sementara yang 'hitam' sama sekali tidak di-blur. Dengan kata lain, Anda mendapat blur ber-mask yang sangat sederhana. Tentu saja hasil ini bisa dicapai dengan banyak cara lain, tetapi itu belum menjelaskan di mana letak kekuatan pemetaan blur. Yang membuat pemetaan blur ini luwes adalah sifatnya yang bervariasi di seluruh gambar. Artinya, bila warna pada peta blur itu abu-abu, hasil blur yang didapat lebih kecil sepadan dengan warnanya, memakai 'tetangga' yang lebih sempit untuk piksel tersebut. Hitam tidak di-blur sama sekali, sedangkan putih di-blur secara maksimum, sesuai nilai yang diberikan. Satu hal yang perlu dicatat: hanya area yang di-blur yang memerlukan waktu tambahan. Piksel yang tidak di-blur tidak membutuhkan pemrosesan ekstra ini. Ini membuat contoh di atas jauh lebih cepat daripada memakai Komposit ber-mask, yang sama saja dengan mem-blur seluruh gambar lalu menggabungkan hasilnya. Penghematan waktu ini bisa lebih penting lagi ketika berurusan dengan blur besar pada area gambar yang sangat kecil. Misalnya, mari kita buat koala itu makin kabur ke arah kakinya...
magick -size 75x75 gradient:black-white blur_map_gradient.gif
magick koala.gif blur_map_gradient.gif \
-compose blur -define compose:args=3 -composite \
blur_koala_gradient.gif
Dan berikut blur yang sama lagi, tetapi memperlihatkan bagaimana blur itu berubah menurut tinggi.
magick blur_map_bool.gif blur_map_gradient.gif \
-compose blur -define compose:args=15 -composite \
blur_edge_gradient.gif
Untuk contoh praktis blur ber-peta variabel, lihat Efek tilt shift pada foto dan Font berbayang blur menurut jarak. Perhatikan bahwa yang dipakai untuk menghasilkan 'warna ter-blur' sebuah piksel adalah lingkungan di sekeliling piksel itu. Artinya, meski Anda menetapkan sebagian gambar untuk tidak di-blur, warna dari area yang tidak di-blur itu tetap dapat ikut dipakai dalam blur piksel di sekitarnya. Jadi, area yang tidak di-blur bukan berarti warnanya tidak dipakai sebagai bagian dari hasil piksel lain yang di-blur. Warna dari area yang tidak di-blur itu dapat 'merembes' ke area ter-blur di sekitarnya. Untuk mem-blur latar belakang tanpa menyertakan piksel latar depan, Anda perlu memakai Teknik read mask agar piksel itu tidak ikut terbaca sebagai bagian dari operasi blur.
Blur eliptis
Pengaturan compose 'Blur' memakai teknik yang berbeda dari Operator Blur atau Gaussian Blur biasa, karena ia diimplementasikan memakai algoritme Resampling area eliptis Gaussian yang dikembangkan untuk resampling gambar berskala sebagai bagian dari Operator distorsi umum. Area eliptis yang dipakai untuk resampling tetangga itu juga membuat metode blur ini lebih luwes daripada blur 'melingkar' seragam biasa yang disediakan operator "-blur" dan "-gaussian-blur". Elips itu sendiri didefinisikan oleh 'width ' dan 'height ' dari sigma untuk area yang di-blur. Elipsnya juga dapat diputar dari kesejajaran ortogonal sebesar 'angle ' yang diberikan (searah jarum jam). Misalnya, pada diagram berikut kita perlihatkan bagaimana warna ter-blur sebuah piksel mengambil warnanya dari area eliptis yang diputar, berdasarkan nilai sigma yang diberikan. Piksel di area itu lalu dirata-ratakan berbobot menurut Filter Gaussian (memakai rumus jarak eliptis) untuk menghasilkan warna ter-blur.
magick koala.gif -compose blur -define compose:args=5x1-30 -composite \) \
elliptical_blur.gif
# ... other commands to create diagram of blur effect ...
Seperti sudah disebut, ini persis metode pencarian warna yang sama dengan yang dipakai Operator distorsi umum untuk menghasilkan warna gambar terdistorsinya, karena metode itu memungkinkan penggabungan berskala (dan terfilter) atas suatu area gambar sumber menjadi satu piksel, terutama pada distorsi ekstrem seperti dicontohkan di Memandang cakrawala jauh. Untuk rincian proses ini lihat Resampling area dan Filter resampling.
Sebagai contoh kendali eliptis yang tersedia untuk pemetaan blur variabel, mari kita pakai titik hitam dengan peta blur bergradien yang sama seperti tadi. Tetapi kali ini kita skalakan elips horizontal yang panjang dan tipis '30x0', bukan lingkaran. Bagian 'x0' mungkin tampak aneh, tetapi pada dasarnya berarti tidak boleh ada blur vertikal yang terlihat, hanya elips setipis mungkin yang masih memberi hasil bagus.
magick -size 75x75 xc: -draw 'circle 36,36 36,8' black_circle.gif
magick black_circle.gif blur_map_gradient.gif \
-compose blur -define compose:args=15x0 -composite \
blur_horizontal.gif
Seperti Anda lihat, besar blur-nya tetap bervariasi mengikuti gambar peta yang diberikan, menghasilkan blur yang sangat sedikit di bagian atas gambar dan sangat banyak di bagian bawah. Tetapi perhatikan juga bahwa tepi bawahnya di-blur secara horizontal dengan sama rata ke kedua arah, tetapi tidak secara vertikal, sehingga menghasilkan pemotongan tajam pada arah vertikal. Dengan memutar elips panjang tipis itu melalui argumen angle ketiga, atau dengan langsung mendefinisikan elips vertikal, gambar dapat di-blur hanya secara vertikal... |
magick black_circle.gif blur_map_gradient.gif \
-compose blur -define compose:args=0x15 -composite \
blur_vertical.gif
![[IM Output]](../static/img/mapping/blur_vertical.gif)
Namun perhatikan bahwa blur-nya tidak diterapkan sama rata! Separuh bagian atas tampak kurang ter-blur dibanding bagian bawah, karena memang begitulah perintah 'gambar pemetaan' itu. Hal ini pada gilirannya mendistorsi gambar sehingga tampak sedikit terpangkas oleh efek blur. Terakhir, mari kita lakukan sekali lagi tetapi dengan elips horizontal yang diputar sebesar sudut tetap 45 derajat. |
magick black_circle.gif blur_map_gradient.gif \
-compose blur -define compose:args=15x0+45 -composite \
blur_angle.gif
![[IM Output]](../static/img/mapping/blur_angle.gif)
Gambarnya mungkin tampak sangat aneh, tetapi itu karena peta blur variabelnya vertikal sementara blur-nya sendiri bersudut, sehingga menghasilkan efek yang ganjil, akibat sudut elips dan sudut peta blur yang tidak sejajar. | Perhatikan bahwa memakai elips panjang dan tipis seperti ini sebenarnya jauh lebih cepat daripada memakai satu lingkaran besar. Nyatanya operator "-blur" memperoleh kecepatannya dengan memakai dua blur horizontal dan vertikal terpisah, sedangkan operator blur "-gaussian" melakukan konvolusi 2 dimensi penuh dengan cara yang lebih sederhana daripada metode komposisi 'Blur' yang baru saja diuraikan.
Blur dengan rasio aspek variabel
Sejauh ini kita mengubah-ubah ukuran area eliptis yang dipakai untuk blur memakai 'peta blur'. Namun meski ukuran elips dan bahkan sudutnya dapat diputar, bentuk dan sudutnya tetap tidak berubah. Nah, 'peta blur' adalah gambar yang tersusun dari tiga kanal warna: red, green, dan blue. Karena kita memakai gambar grayscale, ketiga kanal warna itu punya nilai yang sama. Namun secara internal, lebar elips diskalakan hanya oleh nilai kanal red, sedangkan tingginya diskalakan oleh nilai kanal green. Pengaruh nilai kanal blue umumnya diabaikan, kecuali pada satu kasus khusus yang akan kita lihat nanti. Ini berarti bentuk eliptis atau 'rasio aspek'-nya dapat divariasikan dengan memakai peta berbeda untuk masing-masing kanal red dan green. Sama seperti peta blur biasa, nilai nol (atau 'hitam' pada kanal itu saja) menghasilkan lebar atau tinggi minimal, sedangkan nilai maksimum (atau 'putih') menghasilkan besar blur yang diberikan. Misalnya, di sini saya dapat membagi gambar sehingga dua perempat bagiannya di-blur secara horizontal (kanal red maksimal) sementara area lainnya di-blur secara vertikal (kanal green maksimal). Untuk contoh ini saya membuat peta lebar dan tinggi secara terpisah, sebelum Menggabungkannya menjadi satu 'peta blur' yang kini berwarna. Dalam praktik biasa, peta itu boleh dibuat dengan cara apa pun, atau bahkan memakai peta siap pakai untuk efek blur tertentu.
magick -size 2x2 pattern:gray50 -sample 75x75! blur_map_r.gif
magick blur_map_r.gif -negate blur_map_g.gif
magick blur_map_r.gif blur_map_g.gif -background black \
-channel RG -combine blur_map_aspect.gif
magick black_circle.gif blur_map_aspect.gif \
-compose blur -define compose:args=10x10 -composite \
blur_aspect.gif
Sudut elips tentu saja masih dapat disetel ke nilai tetap. |
magick black_circle.gif blur_map_aspect.gif \
-compose blur -define compose:args=15x15+45 -composite \
blur_aspect_angle.gif
![[IM Output]](../static/img/mapping/blur_aspect_angle.gif)
| Sebelum IM versi 6.5.8-8, ditemukan bug pada penanganan blur eliptis vertikal yang bersudut.
Blur dengan sudut variabel
Sejauh ini sudut elips yang dipakai untuk mem-blur gambar selalu tetap di seluruh gambar. Artinya, elips yang dipakai untuk blur selalu berada pada sudut yang sama, meski rasio aspek elips itu dapat divariasikan dengan memodifikasi kanal red dan green pada peta blur. Sejak IM v6.5.8-8, sudut blur dapat dibuat bervariasi memakai kanal blue pada gambar pemetaan blur. Caranya dengan memberikan dua sudut pada argumen blur. Argumen sudut pertama mendefinisikan sudut untuk nilai nol ('0' atau 'hitam') pada kanal blue, sedangkan sudut kedua mendefinisikan nilai maksimum ('QuantumRange' atau 'putih') kanal blue. Bila hanya satu nilai sudut yang diberikan, sudut itu dipakai untuk nilai nol maupun maksimum kanal blue, yang pada dasarnya berarti sudutnya menjadi tetap, apa pun nilai pada kanal blue gambar 'peta blur'. Itulah sebabnya pada contoh-contoh sebelumnya sudutnya selalu tetap. Misalnya, di sini saya memakai elips yang mem-blur secara horizontal, lalu memvariasikan sudut elips itu memakai kanal blue pada rentang sudut '+0' sampai '+360' mengelilingi pusat gambar. Pembuatan petanya memakai gradien polar, yang rinciannya dapat ditemukan di Gradien terdistorsi. Perhatikan bagaimana saat menempatkan gradien itu ke kanal blue, saya memakai pengaturan warna "-background" bersama Operator Combine untuk memastikan kanal red dan green sama-sama disetel ke nilai maksimum ('putih'), sehingga elips bersudut itu tidak ikut diskalakan. Tentu saja itu berarti pada gambar pemetaan akhir, putih berarti pakai sudut maksimum, sedangkan kuning (atau nilai kanal blue nol) berarti sudut minimum.
magick -size 100x300 gradient: -rotate 90 \
+distort Polar '36.5,0,.5,.5' +repage -flop gradient_polar.jpg
magick gradient_polar.jpg -background white \
-channel B -combine blur_map_angle.jpg
magick koala.gif blur_map_angle.jpg \
-compose blur -define compose:args=5x0+0+360 -composite \
blur_rotated.jpg
Hasilnya, seperti Anda lihat, adalah gambar yang ter-blur secara rotasional. Bandingkan hasilnya dengan peta blur yang dipakai. Di bagian atas gambar, gradiennya entah putih atau hitam, yang dengan argumen yang dipakai berarti elipsnya bersudut 0 atau 360 sehingga elips tetap horizontal. Di bagian bawah gradiennya abu-abu murni, sehingga dipakai sudut di tengah rentang yang diberikan, yaitu 180 derajat. Ini berarti elipsnya kembali horizontal. Tetapi di sisi-sisi gambar, gradiennya abu-abu 25% atau 75%, sehingga sudutnya 90 atau 270 derajat dan elipsnya berputar menjadi vertikal. Semua sudut lain mengikuti pola itu sehingga elipsnya berputar mulus mengelilingi gambar. Namun bagian tengah gambar hasilnya ter-blur dengan sangat aneh! Itu karena ukuran elipsnya tetap dan tidak ikut mengecil sebagaimana mestinya ke arah tengah gambar. Solusinya adalah menyetel ukuran elips itu juga memakai kanal red dan green. Misalnya.
magick -size 106x106 radial-gradient: -negate \
-gravity center -crop 75x75+0+0 +repage gradient_radial.jpg
magick gradient_radial.jpg gradient_radial.jpg gradient_polar.jpg \
-channel RGB -combine blur_map_polar.jpg
magick koala.gif blur_map_polar.jpg \
-compose blur -define compose:args=10x0+0+360 -composite \
blur_polar.jpg
Hasil yang jauh lebih baik. Namun perhatikan, meski hasilnya tampak bagus, elips blur-nya tidak melengkung membentuk busur sebagaimana seharusnya untuk blur rotasional sejati. Karena itu contoh di atas hanyalah hampiran dari blur rotasional sejati. Tetapi untuk jarak blur kecil (yang setara dengan sudut blur), hasilnya cukup baik. Cara yang lebih baik untuk blur rotasional adalah memakai Teknik distorsi polar-depolar khusus, atau Operator Radial Blur yang saat ini namanya keliru. Dengan mengubah rentang sudut yang dipakai untuk sudut elips (kanal blue), contoh di atas dengan mudah dapat diubah menjadi radial blur yang makin kabur seiring jarak dari pusat. |
magick koala.gif blur_map_polar.jpg \
-compose blur -define compose:args=5x0+90+450 -composite \
blur_radial.jpg
![[IM Output]](../static/img/mapping/blur_radial.jpg)
Tetapi Anda juga dapat melakukan jauh lebih banyak daripada blur radial/rotasional itu, karena blur dapat diputar dan diskalakan di mana saja sebesar apa saja di seluruh gambar. Kendalinya total. Misalnya, campuran yang sangat aneh dari keduanya dapat dibuat dengan memakai rentang sudut berbeda sehingga sudut elips blur tidak cocok dengan sudut di sekeliling pusat gambar. |
magick koala.gif blur_map_polar.jpg \
-compose blur -define compose:args=10x0+0+180 -composite \
blur_weird.jpg
![[IM Output]](../static/img/mapping/blur_weird.jpg)
Pada dasarnya kini Anda punya kendali penuh atas bagaimana dan bagian mana dari gambar yang akan di-blur. Dan dengan memakai templat, seluruh pustaka efek blur dapat dibuat.
![[IM Output]](../static/img/images/koala.gif)
![[IM Output]](../static/img/mapping/map_gradient_x.gif)
![[IM Output]](../static/img/mapping/distort_noop.gif)
![[IM Output]](../static/img/mapping/map_gradient-x.gif)
![[IM Output]](../static/img/mapping/distort_mirror_x.gif)
![[IM Output]](../static/img/mapping/map_compress.gif)
![[IM Output]](../static/img/mapping/distort_compress.gif)
![[IM Output]](../static/img/mapping/map_compress_y.gif)
![[IM Output]](../static/img/mapping/distort_compress_2D.gif)
![[IM Output]](../static/img/mapping/distort_compose.gif)
![[IM Output]](../static/img/mapping/distort_compose_default.gif)
![[IM Output]](../static/img/mapping/distort_fx_check.gif)
![[IM Output]](../static/img/mapping/distort_fx_check_correct.gif)
![[IM Output]](../static/img/mapping/map_rot45_x.png)
![[IM Output]](../static/img/mapping/map_rot45_y.png)
![[IM Output]](../static/img/mapping/distort_rot45.gif)
![[IM Output]](../static/img/mapping/map_rot45b_x.png)
![[IM Output]](../static/img/mapping/map_rot45b_y.png)
![[IM Output]](../static/img/mapping/distort_rot45_better.png)
![[IM Output]](../static/img/mapping/map_rot45b_m.png)
![[IM Output]](../static/img/mapping/distort_rot45_masked.png)
![[IM Output]](../static/img/mapping/map_rot45u.png)
![[IM Output]](../static/img/mapping/distort_rot45_unified.png)
![[IM Output]](../static/img/img_photos/lena_orig.png)
![[IM Output]](../static/img/mapping/sphere_lena.png)
![[IM Output]](../static/img/img_photos/mandrill_grid_sm.jpg)
![[IM Output]](../static/img/mapping/spherical_mandrill.png)
![[IM Output]](../static/img/images/rose.png)
![[IM Output]](../static/img/mapping/rose_row_shuffle.png)
![[IM Output]](../static/img/mapping/gradient_sinc.gif)
![[IM Output]](../static/img/mapping/graph_source.gif)
![[IM Output]](../static/img/mapping/displace_graph.gif)
![[IM Output]](../static/img/mapping/displace_graph_3.gif)
![[IM Output]](../static/img/mapping/displace_spot.png)
![[IM Output]](../static/img/mapping/dismap_move.jpg)
![[IM Output]](../static/img/mapping/displace_move.png)
![[IM Output]](../static/img/mapping/mirror_areas.gif)
![[IM Output]](../static/img/mapping/mirror_dismap_x.gif)
![[IM Output]](../static/img/images/dragon_sm.gif)
![[IM Output]](../static/img/mapping/mirror_dismap_y.gif)
![[IM Output]](../static/img/mapping/mirror_displaced.gif)
![[IM Output]](../static/img/mapping/mirror_cracks.gif)
![[IM Output]](../static/img/mapping/mirror_cracked.gif)
![[IM Output]](../static/img/mapping/blur_map_bool.gif)
![[IM Output]](../static/img/mapping/blur_koala_bool.gif)
![[IM Output]](../static/img/mapping/blur_map_gradient.gif)
![[IM Output]](../static/img/mapping/blur_koala_gradient.gif)
![[IM Output]](../static/img/mapping/blur_edge_gradient.gif)
![[IM Output]](../static/img/mapping/elliptical_average.gif)
![[IM Output]](../static/img/mapping/black_circle.gif)
![[IM Output]](../static/img/mapping/blur_horizontal.gif)
![[IM Output]](../static/img/mapping/blur_map_r.gif)
![[IM Output]](../static/img/mapping/blur_map_g.gif)
![[IM Output]](../static/img/mapping/blur_map_aspect.gif)
![[IM Output]](../static/img/mapping/blur_aspect.gif)
![[IM Output]](../static/img/mapping/gradient_polar.jpg)
![[IM Output]](../static/img/mapping/blur_map_angle.jpg)
![[IM Output]](../static/img/mapping/blur_rotated.jpg)
![[IM Output]](../static/img/mapping/gradient_radial.jpg)
![[IM Output]](../static/img/mapping/blur_map_polar.jpg)
![[IM Output]](../static/img/mapping/blur_polar.jpg)