⚠️ Ini adalah situs terjemahan tidak resmi dan tidak berafiliasi dengan ImageMagick Studio LLC. Untuk informasi resmi, lihat halaman asli (https://usage.imagemagick.org/transform/index.html).

Contoh penggunaan ImageMagick -- transformasi gambar

Kata pengantar dan indeks contoh penggunaan ImageMagick
Transformasi bergaya seni

Operasi-operasi ini menghasilkan perubahan besar pada tampilan gambar secara keseluruhan, entah untuk efek visual maupun efek bergaya seni. Namun meski tampilan keseluruhan gambar sudah berubah, sering kali secara dramatis, gambar aslinya sendiri umumnya masih terlihat pada hasilnya.


Transformasi bergaya seni

Border timbul atau tenggelam

Operator "-raise" adalah transformasi gambar yang begitu sederhana sampai-sampai nyaris bukan transformasi. Yang dilakukannya hanyalah menambahkan highlight bevel persegi panjang ke gambar yang sudah ada. |

  magick rose: -raise 5  rose_raise.gif

[IM Output]
Efek tenggelam yang terbalik dapat dihasilkan memakai bentuk 'plus' dari operator ini... |

  magick rose: +raise 5  rose_sunken.gif

[IM Output]
Operator ini agak mirip dengan Frame pada sebuah gambar, tetapi alih-alih menambahkan piksel ekstra sebagai border, operator "-raise" mewarnai ulang piksel tepi gambar. Inilah yang menjadikannya sebuah transformasi gambar. | Sebenarnya Frame gambar dihasilkan dengan menambahkan Border, lalu me-raise-nya!
| Operator ini hanya bekerja pada gambar persegi panjang, dan akan gagal untuk gambar dengan latar belakang transparan, karena perubahan warnanya pun ikut transparan. Pada dasarnya operator ini memang agak bodoh!

Menambahkan border di bagian dalam

Alih-alih menempatkan border di sekeliling bagian luar gambar, pengguna ingin menimpakan border langsung pada tepi gambar itu sendiri. Untuk mendapatkan efek ini, solusinya adalah menggambar persegi panjang yang persis sejajar dengan dimensi gambar. Karena gambar bawaan "rose" berukuran 70×46 piksel, overlay yang dihasilkan sama persis dengan ukuran itu. |

  magick rose: -fill none -stroke navy -strokewidth 11  \
          -draw 'rectangle 0,0 69,45'   inside_border.jpg

[IM Output]
Lebar border yang ditambahkan dikendalikan oleh "-strokewidth" persegi panjang tersebut. Yaitu

{stroke width}  =  {border width} * 2 - 1

Karena itu border 6 piksel di atas memerlukan "-strokewidth" sebesar 11. Kalau ukuran gambarnya tidak diketahui, Shave saja gambarnya lalu tambahkan Border seperti biasa. Cara ini mungkin lebih mudah, meski barangkali tidak seluwes cara sebelumnya. |

  magick rose: -bordercolor green -shave 6x6 -border 6x6 inside_border2.jpg

[IM Output]

Penyebaran piksel acak

"-spread" mengganti warna tiap piksel dengan warna acak dari sekitarnya pada gambar source. Pemilihan acak ini dilakukan sesuai interpolasi piksel dan pengaturan piksel virtual. Sebagai contoh... |

  magick -size 80x40 xc:red xc:blue -append -spread 5 spread_interpolated.png

[IM Output]
Kalau piksel-piksel gambar itu diperiksa, akan terlihat bahwa sebagian piksel punya campuran warna merah dan biru. Artinya, piksel itu diinterpolasi, bukan sekadar disebar atau ditukar. Hal ini makin kentara pada nilai jarak yang kecil. Perhatikan juga bahwa "-spread" turut memakai pengaturan piksel virtual. |

  magick -size 80x80 xc: -virtual-pixel black -spread 10 spread_virtual.png

[IM Output]
Seperti terlihat, hasilnya adalah border yang teracak, sebagian besar berupa piksel virtual hitam murni, meski ada beberapa piksel abu-abu hasil interpolasi di perbatasan antara piksel nyata gambar dan piksel virtual. Untuk mendapatkan efek sebaran piksel yang lebih tradisional, percampuran warna ini dapat dicegah dengan memaksa pencarian warna piksel tertentu memakai "-interpolate Nearest". Untuk menghindari masalah piksel virtual dan kemungkinan 'bias warna tepi', saya sarankan memakai "-virtual-pixel Mirror". Dengan begitu, inilah sebaran piksel acak yang lebih tradisional... |

  magick rose: -interpolate nearest -virtual-pixel mirror \
                -spread 5   spread_rose.png

[IM Output]

Sedang dikerjakan

Masalah utama cara di atas adalah sebagian data piksel gambar bisa hilang. Artinya, pikselnya tidak 'ditukar' melainkan disalin secara acak, sehingga sebuah piksel tertentu bisa terduplikasi atau hilang. Sejak IM v6.9.2-2, "+spread" dapat dipakai untuk benar-benar menukar piksel di dalam gambar, sehingga tidak ada piksel yang terduplikasi ataupun hilang. Setiap piksel gambar asli tetap ada, hanya berpindah ke lokasi baru. Namun karena cara piksel diproses, piksel bisa 'tertukar dua kali'. Artinya, sebuah piksel bisa saja ditukar, lalu terpilih lagi untuk ditukar dengan piksel berikutnya. Akibatnya sebuah piksel bisa melayang lebih jauh daripada yang diminta oleh argumen spread. Penukaran ganda ini juga berarti piksel cenderung menyebar lebih jauh ke arah sudut kanan bawah. Pergerakan itu tentu diimbangi oleh pergeseran yang lebih kecil dari sejumlah besar piksel ke arah kiri atas. Sebagai contoh, di sini saya menyebar piksel dengan gambar aslinya diletakkan di depan sebagai acuan. |

  magick -size 40x40 xc:red xc:blue -append \
          \( +clone +spread 5 \) +append spread_bias.png

[IM Output]
Perhatikan bagaimana sebagian piksel merah menyebar lebih jauh ke bawah, meski ada juga beberapa piksel biru yang menyebar ke atas lebih jauh dari perkiraan (walau ke arah sisi kiri gambar). Masalah ini makin kentara bila argumen jarak untuk spread diperkecil. Solusi untuk masalah penukaran ganda ini tidak mudah, dan kami sedang mencari algoritma 'pengacakan area terbatas' untuk mengatasinya. Namun sementara ini bias arah tersebut setidaknya dapat diredam dengan melakukan spread dua kali, diselingi distorsi Transverse (pencerminan diagonal dari kiri atas ke kanan bawah). |

  magick -size 40x40 xc:red xc:blue -append \
          \( +clone +spread 5 -transverse -spread 5 -transverse \) \
          +append spread_no_bias.png

[IM Output]
Tentu saja ini membuat sebarannya makin kentara dan kurang linear, tetapi setidaknya tanpa bias arah maupun duplikasi atau kehilangan piksel. Tambahan di atas dikembangkan dari sebuah diskusi forum: t=28043 diskusi forum IM rearrange vertical pixel row .

Transformasi foto vignette

Sebuah operator khusus untuk membuat gambar menjadi bulat dengan garis luar yang lembut dan buram. |

  magick rose: -background black -vignette 0x5  rose_vignette.gif

[IM Output]
Dengan memakai sigma nol (atau sangat kecil), blur-nya dapat dihilangkan sehingga menghasilkan frame elips atau oval. Namun perlu dicatat bahwa operator ini sebenarnya tidak memakai elips terbesar yang mungkin, jadi barangkali Anda ingin merakitnya sendiri. |

  magick rose: -background black -vignette 0x0  rose_vignette_0.gif

[IM Output]
Operator ini dapat dipakai dengan transparansi (dan format PNG)... |

  magick rose: -alpha Set -background none -vignette 0x3  rose_vignette.png

[IM Output]
Cara pemberian argumen alternatifnya adalah memakai angka yang sangat besar untuk komponen sigma yang kedua, lalu memakai radius yang pertama untuk menentukan sebaran blur-nya. Ini menghasilkan distribusi 'linear' alih-alih distribusi Gauss yang lebih lazim pada blur vignette. |

  magick rose: -background black -vignette 5x65000  rose_vignette_linear.gif

[IM Output]
Teknik lain untuk vignette yang lebih persegi panjang, yang menghasilkan tepi lembut pada gambar, ditunjukkan di thumbnail dengan tepi lembut.

Transformasi polaroid yang kompleks

Berkat kerja Timothy Hunter (yang terkenal lewat RMagick), operator transformasi "-polaroid" ditambahkan ke IM v6.3.2.

Polaroid® adalah merek dagang terdaftar milik Polaroid Corporation.

Sebagai contoh, di sini saya memberi tampilan polaroid pada sebuah thumbnail foto. Gambarnya adalah pandangan ke arah tangga spiral (menghadap ke bawah), di dalam Arc de Triumph, Paris. Tangganya panjang sekali! |

  magick spiral_stairs_sm.jpg -thumbnail 120x120 \
          -bordercolor white -background black  +polaroid  poloroid.png

[IM Output]
| Perhatikan bahwa gambar hasilnya punya bayangan semitransparan, jadi Anda harus memakai gambar berformat PNG, atau "-flatten" hasilnya ke atas warna latar belakang tetap untuk format GIF atau JPG.
Operator ini sangat kompleks, karena ia menambahkan border (sesuai pengaturan "-bordercolor"), 'menggulung' kertasnya, dan menambahkan gulungan terbalik pada bayangannya. Warna bayangan dapat dikendalikan lewat pengaturan warna "-background". Seperti terlihat di atas, bentuk plus dari operator ini memutar hasilnya sebesar sudut acak. Operator ini membuat indeks foto jauh lebih menarik dan tidak sekaku hasil biasanya. Bentuk minus dari operator ini memungkinkan sudut putaran gambar dikendalikan sendiri. |

  magick spiral_stairs_sm.jpg -thumbnail 120x120 \
          -bordercolor AliceBlue -background SteelBlue4 -polaroid 5 \
          poloroid_5.png

[IM Output]
Kalau gambarnya punya metadata "-caption", teks itu juga akan ditambahkan ke border bawah frame polaroid lewat operator pembuat gambar "caption:". Artinya, teksnya akan dipatahkan per kata mengikuti lebar foto. |

  magick -caption '%c %f\n%wx%h' spiral_stairs_sm.jpg -thumbnail 120x120 \
          -bordercolor Lavender  -background gray40  +polaroid \
          poloroid_captioned.png

[IM Output]
Pengaturan (setting) teks standar lainnya (sesuai "caption:") memungkinkan tampilan caption yang ditambahkan itu diatur sendiri. |

  magick spiral_stairs_sm.jpg -thumbnail 120x120 -font Candice -pointsize 18 \
          -bordercolor Snow -background black -fill dodgerblue -stroke navy \
          -gravity center  -set caption "Spiral Stairs\!"  -polaroid 10 \
          poloroid_controls.png

[IM Output]
| _Atribut metadata gambar "-caption" dipakai karena secara internal digunakan pembuat gambar dari teks "caption:".

Sebaliknya, perintah IM "montage" memakai "-label" karena ia memakai pembuat gambar dari teks "label:" yang tidak memotong per kata._
Penggunaan distorsi shear Rotate dan Wave oleh transformasi ini untuk menambahkan sedikit 'gulungan' pada foto cenderung menghasilkan garis-garis kabur horizontal pada teks di gambar yang dihasilkan. Ini masalah distorsi gambar yang sudah dikenal (lihat memutar garis tipis), dan dapat diatasi dengan teknik super sampling. Pada dasarnya kita membuat polaroid dua kali lebih besar daripada yang sebenarnya diinginkan, lalu tinggal mengubah ukuran gambarnya ke ukuran akhir yang normal. Pengecilan ukuran gambar itu secara efektif menajamkan gambar hasilnya, dan yang lebih penting lagi teks caption-nya. Namun agar cara ini berhasil, kita tidak hanya perlu gambar yang setidaknya dua kali ukuran akhirnya, tetapi mungkin juga perlu border yang lebih besar pada gambar, serta menggambar teksnya pada "-density" dua kali lipat dari biasanya. Jangan menaikkan "-pointsize" font, karena itu tidak memperbesar teks dengan cara yang sama. |

  magick -caption 'Spiral Staircase, Arc de Triumph, Paris, April 2006' \
          spiral_stairs_sm.jpg  -thumbnail 240x240 \
          -bordercolor Lavender -border 5x5   -density 144  \
          -gravity center  -pointsize 8   -background black \
          -polaroid -15     -resize 50%     poloroid_modified.png

[IM Output]
Seperti terlihat, meski kita memakai pointsize font yang jauh lebih kecil, teks caption-nya sangat tajam, jelas, dan terbaca. Begitu pula detail halus lain yang mungkin ada pada gambar aslinya. Satu-satunya kerugiannya adalah bayangan gambar hasilnya jadi lebih kecil dan kurang kabur. Untuk kendali penuh atas transformasi polaroid, seluruh langkahnya bisa dikerjakan sendiri. Teknik aslinya didokumentasikan di halaman Tim Hunter, RMagick Polaroid Effect. Langkah-langkahnya: membuat dan menyambungkan caption, menambahkan border, menggulung foto dengan wave, menambahkan bayangan bergulung terbalik, dan terakhir memutar gambar. Untuk contoh lain serta metode rakitan sendiri lainnya, lihat contoh thumbnail polaroid dan montage foto polaroid. Anda mungkin juga tertarik pada beberapa contoh polaroid di RubbleWeb IM Examples, Other.

Lukisan cat minyak, gumpalan warna

Operator "-paint" dirancang untuk mengubah gambar menjadi lukisan yang dibuat dengan menorehkan 'gumpalan' cat tebal ke atas kanvas. Hasilnya adalah peleburan warna-warna bertetangga menjadi area warna tunggal yang lebih besar.

  magick rose: -paint 1   rose_paint_1.gif
  magick rose: -paint 3   rose_paint_3.gif
  magick rose: -paint 5   rose_paint_5.gif
  magick rose: -paint 10  rose_paint_10.gif
  magick rose: -blur 0x3 -paint 10  rose_blur_paint_10.gif

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

Perhatikan bahwa pada radius gumpalan cat yang besar, gumpalannya mulai tampak kotak-kotak. Efek ini bisa sedikit diperhalus dengan mem-blur gambarnya sedikit sebelumnya, seperti pada gambar terakhir di atas. Efeknya menarik dan bisa dipakai untuk membuat gambar latar belakang yang aneh sekaligus indah. Sebagai contoh lihat penggunaannya di contoh latar belakang. Satu peringatan terakhir. Meski "-paint" semestinya menghasilkan area berwarna polos tunggal, pada nilai radius yang besar operator ini cenderung menghasilkan gradien vertikal di sebagian area. Ini sangat mengganggu, dan mungkin sebuah bug. Ada yang tahu? Ada alternatif selain "-paint". Salah satunya adalah memakai "-statistic Mode", yang memberi tiap piksel 'warna dominan' di dalam ketetanggaan persegi panjang yang diberikan, dan bisa menghasilkan hasil yang lebih bagus. |

  magick rose: -statistic Mode 10 rose_paint_mode.gif

[IM Output]
Alternatif lain adalah memakai sebagian metode morfologi, lebih tepatnya varian Intensity untuk gambar berwarna. Sebagai contoh, berikut morfologi 'OpenIntensity' pada gambar rose. |

  magick rose: -morphology OpenI Disk rose_paint_open.gif

[IM Output]
Dan di sini saya memakai 'CloseIntensity' dengan 'Disk' yang sedikit lebih kecil. |

  magick rose: -morphology CloseI Disk:2.5 rose_paint_close.gif

[IM Output]
Anda tidak harus memakai 'disk'; kernel berbentuk 'kuas' sendiri pun bisa dirancang untuk gumpalan yang dihasilkannya. Misalnya, bagaimana kalau memakai kuas berupa garis diagonal.

Charcoal, sketsa arang sebuah pemandangan

Efek charcoal dimaksudkan untuk menyimulasikan sketsa arang seorang seniman atas gambar yang diberikan. Operator "-charcoal" dalam beberapa hal mirip dengan transformasi deteksi tepi yang dipakai visi komputer. Pada dasarnya ia berusaha mengubah batas dan tepi utama objek di dalam gambar menjadi arsiran pensil dan arang. Satu-satunya argumennya semestinya mewakili ketebalan garis tepi.

  magick rose: -charcoal 1   rose_charcoal_1.gif
  magick rose: -charcoal 3   rose_charcoal_3.gif
  magick rose: -charcoal 5   rose_charcoal_5.gif

[IM Output] [IM Output] [IM Output] [IM Output]

Untuk contoh yang lebih baik tentang penerapan transformasi charcoal pada gambar nyata, lihat sketsa arang sebuah foto. Secara teknis operator "-charcoal" adalah operator "-edge" dengan penerapan ambang batas pada hasil konversi gambar asli ke grayscale.

Transformasi sketsa pensil

Operator "-sketch" pada dasarnya menerapkan pola goresan garis pada sebuah gambar untuk menghasilkan sesuatu yang tampak seperti sketsa pensil bergaya seni. Argumennya mengendalikan panjang dan sudut goresan. Namun operator ini paling baik diterapkan pada gambar yang lebih besar dengan arsiran yang jelas. Lihat sketsa pensil untuk contoh lengkap operator ini dan cara kerjanya secara internal.

Emboss, membuat kesan metalik

Operator "-emboss" berusaha menghasilkan efek cetakan asam dari gambar grayscale pada selembar logam. Dalam banyak hal operator ini sangat mirip dengan operator "-shade" yang akan kita lihat di bawah, tetapi tanpa tepi yang tampak 3D. Argumennya berupa radius/sigma, dan hanya sigma-nya yang penting. Saya sendiri tidak merasa argumen itu berguna, dan boleh jadi memang bermasalah. Argumennya pun berubah pada versi IM yang belakangan. Saya benar-benar tidak tahu apa yang terjadi. Bantu saya memahaminya kalau Anda bisa.

  magick rose: -emboss 0x.5  rose_emboss_0x05.gif
  magick rose: -emboss 0x.9  rose_emboss_0x09.gif
  magick rose: -emboss 0x1   rose_emboss_0x10.gif
  magick rose: -emboss 0x1.1 rose_emboss_0x11.gif
  magick rose: -emboss 0x1.2 rose_emboss_0x12.gif
  magick rose: -emboss 0x2   rose_emboss_0x20.gif

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

Operator ini adalah operator grayscale, artinya ia diterapkan pada ketiga kanal warna secara terpisah. Karena itu sebaiknya hanya diterapkan pada gambar grayscale. Seperti terlihat di atas, gambar berwarna bisa menghasilkan efek yang aneh.

  magick rose: -colorspace Gray  -emboss 0x.5  rose_g_emboss_0x05.gif
  magick rose: -colorspace Gray  -emboss 0x.9  rose_g_emboss_0x09.gif
  magick rose: -colorspace Gray  -emboss 0x1   rose_g_emboss_0x10.gif
  magick rose: -colorspace Gray  -emboss 0x1.1 rose_g_emboss_0x11.gif
  magick rose: -colorspace Gray  -emboss 0x1.2 rose_g_emboss_0x12.gif
  magick rose: -colorspace Gray  -emboss 0x2   rose_g_emboss_0x20.gif

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

 Kalau ada yang tahu persis apa yang semestinya dilakukan algoritma emboss ini,
tolong beri tahu saya.

Stegano, menyembunyikan gambar rahasia di dalam gambar

Operator "-stegano" sebenarnya lebih merupakan operator 'iseng'. Misalnya, ia bisa dipakai mata-mata untuk menyembunyikan informasi di dalam 'kekacauan' sebuah gambar acak. Sebelumnya, satu peringatan...

Jangan gunakan JPEG, GIF, atau pengodean gambar 'lossy' lainnya bersama Stegano

Sebagai contoh, mari kita buat pesan (gambar) rahasia yang ingin Anda kirim ke sesama mata-mata... | |

  magick -gravity center -size 50x40 label:"Watch\nthe\nPidgeon" message.gif
  magick identify message.gif

[IM Output]
| [IM Text]
Perhatikan bahwa kita juga perlu ukuran gambar pesannya (36x43 piksel), karena itulah ada identify di atas. Berikutnya, sisipkan gambar itu ke dalam gambar lain dengan suatu offset. Offset (dan ukuran pesan) yang dipakai adalah 'kunci' kriptografis untuk pesan tersembunyi itu. |

  magick composite message.gif rose: -stegano +15+2  rose_message.png

[IM Output]
Sekarang gambar itu bisa Anda kirim ke rekan Anda, yang diandaikan sudah tahu ukuran dan offset pesannya. Kita lalu dapat memulihkan pesan yang tersembunyi di dalam gambar itu... |

  magick -size 50x40+15+2 stegano:rose_message.png message_recovered.gif

[IM Output]
Makin besar gambar penampungnya, makin baik gambar yang dipulihkan, jadi menyembunyikan gambar kecil di dalam gambar yang lebih besar lebih baik daripada contoh di atas. Sekadar memperlihatkan bagaimana pesan tersembunyi itu disebar ke seluruh gambar penampung, mari kita bandingkan gambar gabungannya dengan gambar aslinya. | |

  magick compare -metric PAE rose: rose_message.png   rose_difference.png

[IM Output]
| [IM Text]
Hasilnya memperlihatkan bagaimana gambar pesan itu dienkripsi dan disebar ke seluruh gambar penampung agar tersembunyi. Metrik 'PAE' yang dikembalikan perintah di atas juga menunjukkan bahwa selisih terbesarnya hanya satu nilai warna dari nilai warna 8 bit yang dipakai gambar ini. Artinya, sangat kecil. Begitu kecilnya sampai perubahan atau modifikasi kecil pada gambar akan merusak pesan yang tersembunyi di dalamnya. Karena selisihnya sekecil itu, JPEG dengan kompresi lossy-nya pun tidak bisa dipakai sebagai format gambar penampung, begitu pula format gambar lossy lainnya (termasuk GIF). Selain itu, dengan 'kunci offset' yang salah pesannya tidak akan didapat... |

  magick -size 50x40+14+2 stegano:rose_message.png message_bad.gif

[IM Output]
Area gambar tempat pesan itu disembunyikan juga bisa dibatasi memakai pengaturan Region. Pengaturan yang sama juga diperlukan saat memulihkan pesannya. Hal ini mungkin membuat pencarian dan pembacaan pesan tersembunyi di dalam gambar besar, apalagi bila dibatasi ke area yang 'ramai', jadi jauh lebih sulit ditentukan. Namun perlu diperingatkan bahwa teknik ini tidak terlalu aman secara kriptografis. Apalagi kalau gambar source aslinya juga tersedia. Analisis frekuensi atas gambarnya umumnya akan memberi tahu penyerang bahwa ada pesan tersembunyi. Sebagai metode perlindungan hak cipta gambar, operator Stegano juga tidak berguna, karena perubahan sekecil apa pun pada gambar akan merusak pesannya, dan dengan begitu keefektifannya. Sebagai alat mata-mata pun teknik ini tidak terlalu bagus, dengan jumlah 'kombinasi' yang sedikit untuk gambar berukuran wajar. Siapa pun yang kira-kira tahu apa yang Anda lakukan mungkin bisa membobolnya dengan cepat. Lebih baik berpegang pada metode kriptografis yang sudah dikenal dan teruji waktu. Satu-satunya kegunaan praktisnya adalah sebagai alat iseng, atau sebagai cara menambahkan noise dalam jumlah sangat kecil ke gambar yang sudah ada.

Mengenkripsi data gambar

Operator "-encipher" dan "-decipher" pada dasarnya mengenkripsi data gambar menjadi kekacauan yang tak beraturan. Artinya, isi gambarnya sendiri sama sekali tidak lagi dikenali sampai gambar itu didekripsi kemudian. Ini bisa dipakai misalnya untuk melindungi gambar sensitif di layanan publik, sehingga hanya orang yang punya frasa sandi rahasia yang nantinya dapat melihatnya. Tetapi sebelumnya, satu peringatan...

Jangan gunakan JPEG, GIF, atau pengodean gambar 'lossy' lainnya bersama enkripsi

Sebagai contoh, mari kita enkripsi gambar pesan rahasia yang kita buat di atas, memakai frasa sandi yang saya simpan di sebuah file yang tidak begitu 'rahasia', "pass_phrase.txt".

  magick message.gif    -encipher pass_phrase.txt  \
          -depth 8 png24:message_hidden.png

[IM Output] [IM Output]

| _Gambar terenkripsi mengandaikan dirinya disimpan memakai format file gambar 8 bit. Karena itu batasan tersebut sebaiknya dipaksakan dengan menetapkan "-depth 8" sebelum penyimpanan akhir ke file keluaran.

"png24" juga diperlukan di atas untuk memastikan keluarannya bukan gambar "png8:" berpalet atau ber-colormap, yang juga tidak bekerja dengan benar._
Seperti terlihat, gambar hasilnya tampak seperti sampah belaka, tanpa petunjuk apa pun tentang isi gambar yang sebenarnya. Sekarang gambar itu bisa Anda terbitkan di web, dan hanya orang yang tahu persis frasa sandi aslinya yang dapat memulihkan data gambarnya... |

  magick message_hidden.png -decipher pass_phrase.txt message_restored.gif

[IM Output]
Namun perlu diperingatkan, kalau data gambarnya rusak dengan cara apa pun, gambar itu tidak akan bisa dipulihkan. Termasuk bila PNG-nya disimpan memakai tipe format gambar grayscale. Karena itu hanya format gambar non-lossy yang bisa dipakai, seperti PNG, MIFF, TIFF, atau bahkan teks enumerasi piksel. Sebaliknya, memakai format gambar lossy seperti JPEG, PNG8, dan GIF akan merusak data gambarnya, sehingga menghancurkan hasil enkripsinya. Perhatikan bahwa metadata apa pun yang mungkin menggambarkan gambar itu tetap terbaca jelas. Artinya, gambar dapat dienkripsi memakai string 'comment' gambar itu sendiri sebagai frasa sandi, atau memakai comment itu setelah dienkripsi dengan kata sandi yang lebih pendek. Ide sederhana yang bisa membuat frasa sandinya lebih bervariasi. Mengenkripsi gambar bisa jadi hanya satu langkah. Membawa hasilnya sedikit lebih jauh dapat menghasilkan gambar yang tidak akan begitu saja terdekripsi tanpa pemrosesan tambahan. Sebagai contoh, di sini saya memakai beberapa distorsi sederhana yang tidak merusak untuk mengecoh siapa pun yang mencoba mendekripsi gambar itu dengan cara biasa.

  echo "password" | magick message.gif -encipher - \
                      -transpose  -depth 8   png24:message_obfuscate.png
  echo "password" | magick message_obfuscate.png -transpose \
                      -decipher -  message_restored_2.png

[IM Output] [IM Output] [IM Output]

Kalau "-transpose" tidak disertakan pada perintah dekripsi di atas, gambarnya tidak akan terdekripsi dengan benar. Perhatikan juga bahwa karena cipher aliran yang dipakai (lihat catatan ahli di bawah), memakai sekadar "-roll" tidak akan mencegah gambar itu terdekripsi, setidaknya sebagian. Perhatikan bahwa di atas saya tidak memakai file untuk menyimpan 'frasa sandi', melainkan mengumpankan frasa itu ke perintah "magick" lewat masukan standar, sehingga program atau perintah lain dapat dipakai untuk meminta frasa itu dari pengguna, membangkitkannya, atau cara lain, alih-alih memakai file teks berisi frasa sandi yang terbaca jelas. Frasa sandinya juga bisa dibangkitkan dari file dan gambar lain yang bebas diunduh. Misalnya, gambar Anda bisa didekripsi memakai signature atau string comment dari sebuah gambar acuan terkenal yang bebas diunduh. Sebagai contoh, di sini saya memakai signature gambar "rose.gif" untuk mengenkripsi lalu mendekripsi gambar "message.gif".

  magick identify -format %# rose.gif |\
    magick message.gif  -encipher - -depth 8    png24:message_signed.png
  magick identify -format %# rose.gif |\
    magick message_signed.png   -decipher -   message_restored_3.png

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

Sejak IM v6.4.8-0, file yang dipakai "-encipher" dan "-decipher" boleh berupa file biner. Karena itu sebuah gambar pun bisa langsung dipakai sebagai frasa sandi.

  magick message.gif   -encipher rose.gif  -depth 8  png24:message_binary.png
  magick message_binary.png   -decipher rose.gif   message_restored_4.png

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

| Sebelum IM v6.4.8-0, file biner akan berhenti pada karakter 'NULL' pertama yang ditemukan. Sesuatu yang akan terjadi cukup awal kalau gambar PNG yang dipakai.
Teknik ini eksak (kecuali sebagian datanya rusak dalam pengiriman). Karena itu teknik ini dapat dipakai untuk mengenkripsi gambar yang berisi informasi tersembunyi lain seperti gambar Stegano. Artinya, sekalipun pihak berwenang berhasil mendekripsi gambarnya, atau memaksa Anda membuka kata sandinya, yang mereka lihat adalah sebuah gambar nyata, tetapi gambar itu belum tentu gambar tersembunyi yang terakhir. | Operator "-encipher" dan "-decipher" ditambahkan ke IM v6.3.8-6, tetapi menuntut opsi "--enable-cipher" disertakan dalam konfigurasi build. Namun sejak IM v6.4.6 (kapan berubahnya?) item konfigurasi itu tidak lagi diperlukan dan menjadi pengaturan konfigurasi standar. Karena itu Anda mungkin bisa langsung memakainya.
| _Cipher-nya diimplementasikan memakai stream cipher yang menyinkronkan diri sendiri, yang dibangun dari sebuah block cipher.

Artinya, unduhan gambar yang hanya sebagian, yang rusak karena kesalahan pengiriman, pun masih bisa didekripsi, walaupun sebagian gambarnya mungkin sudah hancur. Seluruh gambar juga tidak perlu diunduh untuk mendekripsi dan memeriksa bagian yang berhasil diunduh.

Tetapi frasa sandinya tetap dibutuhkan agar ada peluang sama sekali untuk berhasil mendekripsi gambarnya, karena enkripsinya sangat sangat kuat.

_

Pikselisasi sebuah gambar

Pikselisasi gambar pada dasarnya dipakai untuk mengubah gambar menjadi sekumpulan 'piksel' besar berwarna yang hanya memperlihatkan garis luar samar dari gambar aslinya. Kedua tekniknya sama-sama mengecilkan gambar (agar pikselnya lebih sedikit), lalu memperbesarnya sedemikian rupa sehingga terbentuk 'blok piksel', memakai operator Scale atau operator Sample untuk menghasilkan blok warna itu. Yang menentukan warna mana persisnya yang dipakai hanyalah cara gambarnya dikecilkan. Satu sampel piksel tunggal, atau warna rata-rata yang dilebur.

  magick rose: -sample 25%  -scale 70x46\!  rose_pixelate_sampled.gif
  magick rose: -scale  25%  -scale 70x46\!  rose_pixelate_scaled.gif
  magick rose: -resize 25%  -scale 70x46\!  rose_pixelate_resized.gif

[IM Output] [IM Output] [IM Output] [IM Output]

Seperti terlihat, area yang 'di-sample' punya 'piksel' yang jauh lebih tegas (aliased), sedangkan dua cara lainnya memakai warna yang dilebur atau dirata-ratakan, yang cenderung menghasilkan representasi warna yang lebih redup tetapi lebih akurat untuk tiap 'piksel'. Lihat juga Melindungi anonimitas seseorang untuk contoh penerapannya hanya pada area ber-mask yang lebih kecil di dalam gambar, seperti wajah seseorang.

Grid piksel

Memberi grid pada gambar sangat mirip dengan pikselisasi gambar. Dalam hal ini kita hanya ingin memperbesar gambarnya, untuk menghasilkan tampilan detail gambar yang tegas sampai ke tingkat piksel. Biasanya untuk gambar yang sangat kecil. Cara paling sederhananya seperti contoh sebelumnya, cukup Scale gambar kecil itu untuk memperbesar pikselnya.

  magick rose: -crop 10x10+12+20 +resize  grid_input.png
  magick grid_input.png  -scale  1000%  grid_scale.png

[IM Output] [IM Output]

Masalah dengan scaling sederhana adalah di area yang warna pikselnya mirip, 'blok piksel' satu per satu jadi sulit terlihat. Yang kita perlukan adalah menambahkan border di sekeliling piksel untuk memisahkannya. Untuk itu kita perlu menimpakan mask tile yang dibangkitkan. Lihat Tiling dengan gambar yang sudah ada di memori untuk berbagai metode memakai gambar tiling yang dibangkitkan dalam satu perintah. Di sini kita membangkitkan 'grid' putih di atas hitam yang ditimpakan memakai komposisi Screen (menimpakan yang putih, sementara area hitam dibiarkan apa adanya). |

  magick -size 10x10 xc: -draw 'rectangle 1,1 9,9' -write mpr:block +delete \
          grid_input.png -scale 1000% -size 101x101 tile:mpr:block \
          +swap -compose screen -composite grid_blocks.png

[IM Output]
Perhatikan bahwa ukuran yang dipakai untuk membangkitkan tile adalah _scale_ *_image_size_ +_gap_size_ (dalam hal ini 10*10+1 => 101). Saya juga menukar kedua gambarnya agar ukuran gambar akhirnya berasal dari gambar tile, bukan dari gambar yang di-scale yang ukurannya satu piksel lebih kecil. Namun cara ini bisa menghilangkan metadata gambar yang ada pada gambar asli, karena saya memakai gambar tile sebagai tujuannya. Di sini saya membangkitkan 'bercak' warna berbentuk lingkaran, tetapi kali ini memakai komposisi Multiply (menimpakan yang hitam, sementara area putih dibiarkan apa adanya). |

  magick -size 10x10 xc: -draw 'circle 5,5 1,3' -negate \
               -write mpr:spot +delete \
          grid_input.png -scale 1000% -size 101x101 tile:mpr:spot \
          +swap -compose multiply -composite grid_spots.png

[IM Output]
Border grid-nya bisa dibuat transparan dengan turut menegasikan overlay tile-nya (area hitam menjadi transparan) lalu memakai komposisi CopyOpacity alih-alih Multiply. Warna lain juga bisa ditambahkan, tetapi agar ini bekerja Anda harus memakai gambar tile yang benar-benar mengandung transparansi nyata. Untuk itu gambar tile hitam-putih tadi perlu diubah menjadi mask berbentuk. Sebagai contoh, di sini saya memakai operator morfologi dasar untuk membangkitkan 'lubang' berbentuk wajik pada overlay berwarna. Untuk itu satu piksel 'benih' digambar lalu diperluas memakai kernel morfologi Diamond. |

  magick -size 10x10 xc: -draw 'point 5,5' -morphology Erode:4 Diamond \
          -background Navy -alpha shape -write mpr:diamond +delete \
          grid_input.png -scale 1000% -splice 1x1+0+0 \
          -size 101x101 -background none tile:mpr:diamond \
          -alpha set -compose Over -composite grid_diamonds.png

[IM Output]
| Perhatikan bahwa coder "tile:" akan mengganti transparansi apa pun di dalam gambar dengan warna latar belakang saat ini. Kalau transparansi gambar tiling itu ingin dipertahankan, tetapkan "-background none" atau "-compose Src". Yang pertama lebih mudah.
Secara teknis, pembentukan alpha itu bisa dilakukan sebelum menyimpan gambar tile, atau setelah men-tile gambar tile tersebut, sebelum ditimpakan. Pilihannya terserah Anda. Satu teknik terakhir adalah memakai filter resampling yang buruk untuk menghasilkan kegagalan resampling sehingga tiap piksel menjadi lingkaran aliased. Ini bukan teknik yang bagus (menyalahgunakan kegagalan pemrosesan gambar), tetapi hasilnya memang membentuk grid piksel.

Memberi jarak antara tile

Masalah serupa adalah memberi jarak pada grid tile di dalam sebuah gambar. Ini bukan sekadar memperbesar piksel satu per satu menjadi 'blok piksel', melainkan menyisipkan ruang di antara area persegi panjang sebuah gambar. Artinya, Splice piksel tambahan ke dalam gambar pada selang yang teratur. Saat ini solusi terbaiknya adalah memecah gambar menjadi baris dan kolom lalu Splice ruang tambahan itu ke tiap tile sebelum menyambung tile-tile itu kembali. Sebagai contoh...

  magick rose: -background SkyBlue \
          -crop 10x0 +repage -splice 3x0 +append \
          -crop 0x10 +repage -splice 0x3 -append \
          grid_tile.png

[IM Output] [IM Output]

Berikut metode lain yang juga memisahkan gambar asli menjadi tile, tetapi kemudian memakai ekspresi FX rakitan sendiri untuk menghitung posisi baru sebuah tile dari posisi lamanya. |

  magick rose: -crop 10x10 \
          -set page '+%[fx:page.x+3*page.x/10]+%[fx:page.y+3*page.y/10]' \
          -background skyblue -layers merge +repage  grid_tile_fx.png

[IM Output]
Angka '3' di atas adalah lebar celah yang ditambahkan, dan '10' adalah ukuran tile-nya. Yang tersisa hanyalah menambahkan border atau tepi lain pada hasilnya. Dengan sedikit kerja tambahan, 'jitter' acak bahkan bisa ditambahkan pada penempatan tiap tile di grid di atas, untuk efek yang kurang teratur. Masalah kedua metode ini adalah membangkitkan banyak gambar kecil hanya untuk disatukan kembali memang menimbulkan banyak pekerjaan. Terutama untuk ukuran tile yang sangat kecil. Metode yang lebih baik yang pernah diusulkan adalah perluasan khusus pada operator Splice, dalam diskusi forum IM Splice (adding tile gridding gaps).


Transformasi visi komputer

Deteksi tepi

Operator "-edge" menonjolkan area gradien warna di dalam sebuah gambar. Ini operator grayscale, jadi diterapkan pada masing-masing dari ketiga kanal warna secara terpisah.

  magick mask.gif -edge 1   mask_edge_1.gif
  magick mask.gif -edge 2   mask_edge_2.gif
  magick mask.gif -edge 3   mask_edge_3.gif
  magick mask.gif -edge 10  mask_edge_10.gif

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

Seperti terlihat, tepi hanya ditambahkan pada area yang gradien warnanya lebih dari 50% putih! Saya tidak tahu apakah ini bug atau memang disengaja, tetapi artinya tepi pada contoh di atas hampir seluruhnya terletak di bagian putih gambar mask aslinya. Fakta ini bisa sangat penting saat memanfaatkan hasil operator "-edge". Misalnya, kalau deteksi tepi dijalankan pada gambar yang mengandung garis luar hitam, operator "-edge" akan 'mengembarkan' garis hitam itu sehingga hasilnya jadi aneh.

  magick piglet.gif  -colorspace Gray  -edge 1 -negate  piglet_edge.gif

[IM Output] [IM Output]

Namun dengan menegasikan gambarnya sebelum melakukan deteksi tepi, garis kembar itu bergerak ke dalam dan menyatu, sehingga efek 'garis kembar' itu hilang. |

  magick piglet.gif -colorspace Gray \
                 -negate -edge 1 -negate    piglet_edge_neg.gif

[IM Output]
Saya mendapati tepinya cenderung terlalu tajam, sehingga gambar hasilnya bertepi tidak mulus. Karena itu menurut saya blur yang sangat sangat tipis pada hasilnya cukup banyak memperbaiki tampilannya. |

  magick piglet_edge_neg.gif  -blur 0x.5  piglet_edge_blur.gif

[IM Output]
Di sini saya menerapkan deteksi tepi pada gambar berwarna, dan pada versi grayscale-nya, untuk memperlihatkan efeknya pada gambar yang mirip foto.

  magick rose:                  -edge 1  rose_edge.gif
  magick rose: -colorspace Gray  -edge 1  rose_edge_grey.gif

[IM Output] [IM Output]

Seperti terlihat, tanpa mengonversi gambarnya ke grayscale, tepi untuk tiap kanal warna dibangkitkan sepenuhnya lepas satu sama lain.

Detektor tepi Canny

Sejak IM v6.8.9-0, IM mendukung detektor tepi Canny. (Lihat contoh pengumumannya di forum IM). Ini algoritma deteksi tepi yang sangat canggih, yang menghasilkan garis selebar satu piksel yang sangat tegas (biner) pada semua tepi tajam, dengan gangguan noise yang sangat sedikit. Sebagai contoh, di sini kita terapkan pada gambar uji yang kita pakai di atas..

  magick mask.gif           -canny 0x1+10%+30%  mask_canny.gif
  magick piglet.gif         -canny 0x1+10%+30%  piglet_canny.gif
  magick piglet.gif -negate -canny 0x1+10%+30%  piglet_canny_neg.gif
  magick rose:             -canny 0x1+10%+30%  rose_canny.gif

[IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]

Seperti terlihat, hasilnya jauh lebih tajam daripada operator Edge di atas. Tepi ter-anti-alias yang kabur nyaris tidak berpengaruh pada hasilnya, yang berupa garis bitmap tipis. Seperti tampak pada gambar piglet, hasilnya juga tidak diletakkan pada satu sisi tertentu seperti yang dilakukan operator edge sebelumnya. Akibatnya, menegasikan gambar masukan tidak berpengaruh. Tetapi seperti semua detektor tepi, ia bisa bermasalah pada gambar dunia nyata dengan latar belakang yang 'ramai', seperti gambar rose bawaan. Hasil yang bersih ini sangat penting nanti pada deteksi garis Hough.

Garis tepi dari bentuk ter-anti-alias

Masalah terbesar metode deteksi tepi biasa adalah hasilnya sangat aliased. Artinya, ia menghasilkan efek piksel yang sangat bertangga, terlepas dari apakah bentuknya mulus (ter-anti-alias) atau aliased. Sebagai contoh, berikut balon ucapan yang mulus dan ter-anti-alias (karakter ')' dari font "WebDings"). |

  magick -size 80x80 -gravity center -font WebDings label:')' voice.gif

[IM Output]
Dan berikut gambar hasil deteksi tepinya... |

  magick voice.gif -edge 1 -negate   voice_edge.gif

[IM Output]
Seperti terlihat, hasilnya jelek sekali: ada sedikit anti-aliasing di sisi luar tepinya, dan tampilan yang benar-benar aliased (bertangga) di sisi dalam garisnya. Menegasikan gambarnya menghasilkan garis luar yang serupa di sekeliling bagian luar gambar, tetapi aliasing-nya kuat di luar garis. |

  magick voice.gif -negate -edge 1 -negate   voice_edge_negate.gif

[IM Output]
Alternatif bila gambar yang ada sudah bertepi ter-anti-alias adalah membangkitkan gambar selisih terhadap salinan bentuk aslinya yang di-'jitter'. Sebagai contoh, di sini kita mencari gambar selisih antara gambar asli dan gambar yang di-offset (atau di-jitter) satu piksel ke kanan. |

  magick voice.gif \( +clone -roll +1+0 \) -compose difference -composite \
          -negate   voice_jitter_horiz.gif

[IM Output]
Perhatikan bahwa cara ini tidak menghasilkan tepi yang baik untuk tepi yang melandai horizontal. Namun dengan menggabungkan gambar selisih hasil jitter horizontal dan vertikal, kita bisa mendapat garis luar bentuk yang ter-anti-alias dengan sangat baik. |

  magick voice.gif \
          \( -clone 0 -roll +1+0 -clone 0 -compose difference -composite \) \
          \( -clone 0 -roll +0+1 -clone 0 -compose difference -composite \) \
          -delete 0  -compose screen -composite -negate  voice_jitter_edge.gif

[IM Output]
Teknik ini juga punya kelebihan: ia bekerja terlepas dari apakah mask-nya dinegasikan atau tidak. Namun perhatikan bahwa hasilnya punya offset setengah piksel relatif terhadap gambar asli, sehingga mungkin perlu pemrosesan 'distorsi' lanjutan untuk menyelaraskan kembali bentuk aslinya atau garis luarnya, kalau keduanya perlu digabungkan demi hasil yang Anda inginkan.

Garis tepi dari bentuk bitmap

Gambar bitmap jauh lebih sulit, karena tidak punya piksel ter-anti-alias yang bisa dipakai untuk menghasilkan garis luar yang mulus. Sebagai contoh, berikut bentuk 'Heart' yang bergaya, yang diambil dari font "WebDings" (karakter 'Y'). Namun sengaja saya bangkitkan sebagai bitmap yang aliased, untuk menyimulasikan gambar bitmap jelek yang diunduh dari jaringan. Misalnya garis luar gambar GIF yang mengandung transparansi. |

  magick +antialias -size 80x80 -gravity center \
          -font WebDings label:Y   heart.gif

[IM Output]
Jadi kita punya gambar jelek ini, tetapi yang ingin kita cari adalah garis luarnya, bukan bentuknya. Pemakaian deteksi tepi secara langsung hanya akan menghasilkan tepi bitmap murni di sekeliling bagian luar bentuk bitmap itu. |

  magick heart.gif -edge 1 -negate   heart_edge.gif

[IM Output]
Tepi yang dinegasikan menghasilkan gambar tepi, tetapi untuk sisi dalam area hitamnya. |

  magick heart.gif -negate -edge 1 -negate   heart_edge_negate.gif

[IM Output]
Dengan menjumlahkan keduanya, didapat tepi selebar 2 piksel yang terpusat pada tepi bentuk bitmap itu. |

  magick heart.gif \( +clone -negate \) -edge 1 \
          -compose add -composite  -negate  heart_edge_double.gif

[IM Output]
Seperti terlihat, gambar hasilnya sangat aliased dengan efek 'bertangga' pada garis luarnya, meski gambar aslinya sendiri sebenarnya tidak terlalu buruk dalam hal ini. Ini bukan solusi yang bagus. Tepi yang sedikit lebih baik bisa dibuat memakai metode morfologi 'EdgeIn', atau metode lain yang serupa. |

  magick heart.gif  -negate -morphology EdgeIn Diamond -negate heart_edgein.gif

[IM Output]
Efek serupa bisa dicapai hanya dengan memakai beberapa kali pengubahan ukuran untuk mem-blur tepinya dengan cara yang tepat, sebelum memakai Solarize untuk mengekstrak piksel abu-abu tengah yang membentuk tepi itu. Tepi yang lebih tebal bisa dihasilkan dengan menambahkan pengaturan "-filter Cubic", atau filter resampling lainnya. |

  magick heart.gif -resize 400% -resize 25% \
          -solarize 50% -evaluate multiply 2 -negate heart_resize.gif

[IM Output]
Atau untuk efek kabur yang lebih terkendali, bentuknya cukup di-blur lalu tepinya diekstrak dengan cara serupa. Menurut saya blur '0.7' kira-kira yang terbaik, dengan batas 3 piksel supaya lebih cepat. |

  magick heart.gif -blur 3x.7 -solarize 50% -level 50%,0 heart_blur.gif

[IM Output]
Perhatikan penggunaan operator Level, yang setara dengan "-evaluate multiply 2 -negate" pada contoh sebelumnya. Dengan border yang ter-anti-alias, bentuk aslinya kini bisa ditambahkan kembali kalau yang diinginkan hanyalah memuluskan bentuk aslinya, bukan mendapatkan garis luarnya. Ingat saja bahwa garis luarnya terletak persis di sepanjang tepi gambar asli, jadi ukurannya akan setengah piksel lebih besar daripada contoh-contoh sebelumnya. Apakah Anda tahu cara lain untuk menghasilkan garis luar ter-anti-alias dari sebuah bentuk (ter-anti-alias maupun bitmap)? Kalau ya, tolong kirimkan ke saya atau ke forum IM. Nama Anda akan dicantumkan.

Membuat tepi memakai konvertor raster ke vektor

Salah satu solusi paling ideal adalah memakai program konversi 'raster to vector ' di luar IM untuk mengubah bentuk bitmap ini menjadi garis luar vektor. Program yang bisa melakukannya antara lain: "ScanFont", "CorelTrace", "Streamline" dari Adobe, dan "Vector Magic". Namun kebanyakan di antaranya menuntut biaya, setidaknya sedikit. "VectorMagick" dan program tracing lain, "AutoTracer", menyediakan konverter gambar daring yang bebas dipakai. Solusi gratis lainnya adalah "AutoTrace" atau "PoTrace". Saran lain sangat diterima. Program trace ini mudah dipakai, tetapi biasanya menuntut semacam persiapan gambar sebelum dan sesudahnya. Format masukannya terbatas, dan keluarannya berupa gambar vektor yang akan membentuk versi 'termuluskan' dari gambar masukan. Saya lebih suka "AutoTrace" karena ia tidak menskalakan data SVG hasilnya sehingga ketebalan garisnya standar, walau program ini tidak bisa dipakai dalam 'pipeline'. Untuk hasil terbaik, sebaiknya kita pastikan yang diumpankan hanyalah gambar bitmap sederhana, yang bisa kita jamin dengan menerapkan ambang batas pada gambar masukan sekaligus mengonversinya ke format gambar yang dipahami autotrace. Setelah itu saya bisa mengubah gambar tersebut menjadi gambar vektor SVG.

  magick heart.gif -colorspace gray -threshold 50% heart_tmp.pbm
  autotrace -output-format svg -output-file heart.svg heart_tmp.pbm
  magick heart.svg heart_svg.gif
  rm -f heart_tmp.pbm

[IM Output] | | | [IM Text]
| [IM Output]

Sejak IM v6.4.2-6, urutan di atas dapat dilakukan langsung memakai delegate masukan gambar "autotrace:". Ini hanya menuntut perintah "autotrace" terpasang. Sebagai contoh |

  magick autotrace:heart.gif  heart_traced.gif

[IM Output]
Kalau IM Anda dibangun dengan pustaka delegate "AutoTrace", IM juga bisa langsung membangkitkan gambar SVG dari gambar yang ada di memori. Untuk rinciannya lihat penanganan keluaran SVG. Sebagai contoh....

  magick heart.gif  heart_2.svg

[IM Text]

Tentu saja keluaran SVG itu mewakili versi yang sudah dimuluskan dari gambar asli, dan itu bukan yang sebenarnya kita inginkan pada contoh ini. Tetapi karena kita kini punya bentuk bitmap tersebut dalam vector form , kita tinggal menyesuaikan atribut 'style' SVG-nya agar garis luarnya di-'stroke', bukan bentuknya di-'fill'. SVG yang sudah diubah itu lalu bisa diumpankan kembali ke ImageMagick untuk membuat ulang gambar raster bergaris luar yang bersih. Sebagai contoh... |

  cat heart.svg |
    sed 's/"fill:#000000[^"]*"/"fill:none; stroke:black;"/' |
      magick svg:- heart_outline.gif

[IM Output]
Ya, caranya memang agak merepotkan, tetapi hasil mulus yang ter-anti-alias itu sepadan dengan usahanya. Alangkah baiknya kalau garis luar atau modifikasi lain bisa ditentukan sebagai opsi pada perintah "autotrace" itu sendiri, tetapi saat ini fitur itu belum ada. Keluaran SVG-nya juga bisa dimodifikasi lebih jauh untuk menebalkan tepinya, atau menentukan warna stroke maupun latar belakang yang lain, dan mengubah warna fill bentuk tepi vektornya. Sebagai contoh, di sini kita menghasilkan garis luar bentuk yang lebih tebal dengan isian merah, semuanya ter-anti-alias dengan rapi. |

  cat heart.svg |
    sed 's/"fill:#000000;[^"]*"/"fill:red; stroke:black; stroke-width:5;"/' |
        magick svg:- heart_outline_thick.gif

[IM Output]
Bentuk hati sesempurna itu tidak mungkin dihasilkan dari bentuk bitmap dengan cara lain. Kita juga bisa sekadar mengekstrak elemen path 'd="..."' untuk dipakai langsung sebagai string path SVG pada perintah Draw. Dengan begitu pengaturan draw IM lainnya dapat dipakai bersama garis luar vektor tersebut, sehingga hasil akhirnya sepenuhnya terkendali. Untuk contoh lain penggunaan program "AutoTrace", lihat skeleton memakai Autotrace.

Detektor garis Hough

Detektor garis Hough ("-hough-lines" ditambahkan di IM v6.8.9-1) adalah transformasi yang sangat kompleks dengan banyak tahap (untuk rinciannya lihat Wikipedia, transformasi Hough). Pada dasarnya ia dirancang untuk memeriksa sebuah gambar, mencari garis putih di atas latar belakang hitam, dan berusaha mengembalikan lokasi persis segmen garis mana pun (deret piksel yang lurus) yang ada di dalam gambar. Ini bisa sangat penting untuk hal seperti menghilangkan rotasi gambar, atau menentukan transformasi perspektif pada sebuah gambar sehingga transformasi itu dapat diulang atau dihilangkan. Berikut seluruh opsi untuk operator ini

  -background {_background_} -stroke {_line_color_} -hough-lines {_W_}x{_H_}+{_threshold_}

Warna-warnanya (background dan line_color) dipakai untuk menetapkan warna garis pada gambar hasil (kalau garisnya memang digambar). Argumen untuk operator Hough (W}x{H}+{threshold) dipakai untuk menentukan ukuran dan ambang batas filter yang dipakai mencari 'puncak' pada 'gambar pencarian' antara. Artinya, argumen itu mengendalikan seberapa baik ia benar-benar 'menemukan' garis yang ingin kita deteksi (lihat di bawah). Nilai-nilai ini disesuaikan untuk membantu deteksi garisnya. Sebagai contoh, mari kita coba menemukan garis pada gambar berbentuk persegi panjang. Pertama kita perlu menyederhanakan gambarnya menjadi garis, dan untuk hasil yang bersih detektor tepi Canny dianjurkan.

  magick shape_rectangle.gif -canny 0x1+10%+30% rectangle.gif

[IM Output] [IM Output]

Sekarang mari kita terapkan detektor garis Hough pada gambar ini. |

  magick rectangle.gif -background black -stroke red \
          -hough-lines 5x5+20   rectangle_lines.gif

[IM Output]
Seperti terlihat, 5 garis ditemukan, 2 di antaranya sangat berdekatan. Alasan munculnya garis tambahan itu adalah persegi panjang di dalam gambarnya tidak sempurna. Nah, meskipun saya menampilkan hasilnya sebagai gambar raster (GIF), operator Hough sebenarnya membangkitkan gambar vektor dalam format Magick Vector Graphics. Artinya informasi garisnya bisa didaftar untuk pemrosesan lanjutan.

  magick rectangle.gif -background black -stroke red \
          -hough-lines 5x5+20   rectangle_lines.mvg

[IM Text]

Perhatikan bahwa garis-garisnya digambar dari satu tepi gambar (dengan nilai floating point) ke tepi yang lain. Dari sini terlihat bahwa garis kedua dan ketigalah yang berdekatan. Komentar pada keluaran MVG memberikan jumlah akumulasi piksel yang 'dikenai' garis itu di dalam gambar, sehingga menjadi petunjuk yang baik tentang seberapa kuat garis tersebut pada gambar. Nilai ini akan selalu lebih besar daripada nilai ambang batas yang diberikan ke operator "-hough-line". Dari sini terlihat bahwa garis pertama dan terakhir (yang saling berdekatan) kekuatannya kira-kira sama, sehingga sulit memilih salah satunya. Kalau Anda mengalami hal ini, saya sarankan tahap deteksi tepinya diperbaiki. Perhatikan bahwa gambar MVG itu tidak mendefinisikan warna apa pun. Pengaturan warna pada contoh ini sebenarnya tidak dipakai. Warnanya baru dipakai kalau vektornya benar-benar 'digambar' saat mengonversi hasil di atas menjadi gambar 'raster', seperti yang kita lakukan sebelumnya. 'Gambar pencarian' antara, atau 'akumulator', yang mencari piksel putih pada tiap orientasi juga bisa dilihat memakai define khusus. |

  magick rectangle.gif \
          -define hough-lines:accumulator=true -hough-lines 5x5+20 \
          -delete 0 -contrast-stretch 0.1% rectangle_accumulator.gif

[IM Output]
Define itu hanya menyambungkan 'gambar pencarian' ke gambar hasil, yang dalam hal ini kita hapus. Kita juga menerapkan sedikit kontras pada 'nilai akumulasi' agar lebih terlihat. Inilah gambar yang ditelusuri oleh argumen-argumen detektor Hough. Gambarnya selalu selebar 180 piksel (1 piksel per derajat sudut garis), sedangkan tingginya dua kali panjang diagonal gambar. Karena itu letak puncaknya langsung menentukan sudut garis serta jarak tegak lurus garis itu relatif terhadap titik pusat gambar masukan. Artinya koordinat X adalah sudut dalam derajat, dan koordinat Y adalah jarak dari pusat, dari -jarak diagonal sampai +jarak diagonal. Kalau puncak di kanan bawah diamati dengan saksama, akan terlihat mengapa kita berakhir dengan dua garis alih-alih satu. Puncak di situ 'kembar' dengan celah tipis di antaranya. Algoritmanya berdasarkan skrip "houghlines" karya Fred Wienhaus, meski dengan penanganan akumulasi 'jarak tegak lurus' yang berbeda.


Ambang batas adaptif lokal

Sedang dikerjakan

Operator "-lat" mencoba menerapkan ambang batas pada setiap piksel secara adaptif, berdasarkan nilai piksel di dalam jendela sekitarnya. Cara ini biasa dipakai untuk mengambangkan gambar yang latar belakangnya tidak rata (yaitu, penerangannya tidak merata). Dasarnya adalah asumsi bahwa piksel di dalam sebuah jendela kecil kurang lebih punya warna latar belakang yang sama dan warna latar depan yang kurang lebih sama pula.

Sebagai contoh.
   magick input.png -lat 17 output.png

Pada contoh di atas, sebuah 'jendela' persegi berukuran 17 piksel dipakai untuk menentukan warna rata-rata gambar di setiap titik; bila pikselnya lebih gelap daripada rata-rata itu, piksel dijadikan hitam, dan bila lebih terang, dijadikan putih. Ukuran jendela yang kecil membuat ambang batas lebih peka terhadap perubahan penerangan yang kecil, lebih cepat dihitung, tetapi terpengaruh buruk oleh noise di dalam gambar.

Contoh

Ukuran jendela yang lebih besar membuat ambang batas kurang peka terhadap perubahan penerangan yang kecil, lebih lambat dihitung, dan tidak terlalu terpengaruh oleh noise di dalam gambar. Efeknya, pemilihan nilai ambang batas menjadi lebih peka atau kurang peka terhadap perubahan kecil pada nilai piksel.

Contoh


Jendela tidak harus persegi.  misalnya...
  magick input.png -lat 15x25 output.png

Anda juga dapat memberikan offset yang akan ditambahkan ke warna rata-rata hasil hitungan, sehingga nilai ambang batas lokal untuk setiap piksel menjadi lebih terang atau lebih gelap. Ini misalnya dapat dipakai untuk mengurangi pengaruh noise atau pengaruh perubahan kecil pada nilai piksel.

  magick input.png -lat 15x25+2%

Perubahan kecil semacam ini biasanya muncul ketika gambar diambil dengan pemindai atau kamera digital. Gunakan nilai offset positif agar pengambangan adaptif kurang peka terhadap variasi kecil pada nilai piksel. Gunakan ambang batas negatif agar pengambangan adaptif lebih peka terhadap variasi kecil pada nilai piksel. Sebagai alternatif, noise di dalam gambar dapat dikurangi lebih dulu sebelum diproses dengan "-lat".

Ringkasnya, setiap piksel diambangkan dengan logika berikut:
  AVG = nilai rata-rata setiap piksel di dalam jendela
  IF (piksel masukan > AVG + OFFSET)
     Piksel keluaran HITAM
  else
     Piksel keluaran PUTIH

---

Alternatif lain adalah mengurangkan salinan gambar asli yang sudah di-blur
memakai Subtraction (Modulus), lalu mengambangkannya.

   magick rose: -colorspace gray -lat 10x10+0% x:

kurang lebih setara dengan...

   magick rose: -colorspace gray \( +clone -blur 10x65535 \) \
           -compose subtract -composite -threshold 50%  x:

Operator khusus "-blur 10x65535"  adalah blur perataan linear yang membatasi diri pada
jendela 10x10.

Komposisi 'Subtract', karena secara matematis merupakan operasi bertipe modulus, akan
membungkus nilai yang menjadi negatif kembali ke nilai yang lebih besar dari 50%.

Bila Anda ingin menyertakan offset, lakukan dengan mengurangkan juga sebuah gambar latar
berwarna polos memakai -flatten...  misalnya

   magick rose: -colorspace gray -lat 10x10+10% x:

kurang lebih setara dengan...

   magick rose: -colorspace gray \( +clone -blur 10x65535 \) \
           -compose subtract -background gray10 -flatten -threshold 50%  x:

Bagian di atas dimodifikasi dari catatan awal yang diberikan oleh D Hobson dhobson@yahoo.com


   -adaptive-sharpen
        Menajamkan gambar hanya di sekitar tepi gambar

   -segment cluster-threshold x smoothing-threshold
         Segmentasi ruang warna (bukan objek gambar)
         Ini bisa menghasilkan keluaran yang sangat panjang.
         Ini menerapkan "fuzzy c-means algorithm", bila Anda ingin tahu lebih jauh.

Yang juga berkaitan adalah -despeckle. untuk membuang piksel tunggal yang warnanya menyimpang.

Menghasilkan stereogram 3d dari dua gambar (satu untuk masing-masing mata)
Ini dikenal juga sebagai anaglyph
  magick composite left.jpg right.jpg -stereo anaglyph.jpg

Highlight 3D dengan Shade

Menggunakan Shade

Operator "-shade" selalu saya anggap salah satu operator paling menarik yang disediakan ImageMagick. Dokumentasinya hanya memberi petunjuk kasar tentang kemampuan operator ini. Saya perlu banyak riset pribadi untuk memahaminya, bahkan untuk mencari tahu cara terbaik memanfaatkan kekuatan yang bisa diberikannya kepada pengguna IM. Pada dasarnya operator ini menganggap gambar yang diberikan sebagai sesuatu yang disebut 'height field'. Yaitu, sebuah gambar grayscale yang mewakili permukaan suatu benda, atau bentang alam. Warna 'white' mewakili titik tertinggi dalam gambar, sedangkan 'black' titik terendah. Representasi ini berasal dari riset visi komputer tahun 1980, ketika sebuah foto dengan 'lampu kamera' yang kuat dipakai sehingga titik yang dekat menjadi terang dan titik yang jauh menjadi gelap. Karena "-shade" memerlukan gambar grayscale, operator ini otomatis membuang semua warna dari gambar masukan. Begitu pula transparansi yang mungkin ada dalam gambar sama sekali tidak berguna dan diabaikan oleh operator ini.
Nah, "-shade" mengambil height field grayscale ini lalu menyorotkan cahaya ke atasnya. Hasilnya adalah gambaran bayangan cahaya yang akan terbentuk karenanya. Ingat, Anda harus membayangkan gambar masukan sebagai sebuah 'permukaan' agar keluarannya masuk akal. Untuk demonstrasi kita perlu sebuah gambar 'height field', jadi mari kita gambar satu.
  magick -font Candice -pointsize 64 -background black -fill white \
          label:A  -trim +repage -bordercolor black -border 10x5 \
          shade_a_mask.gif

[IM Output]
Gambar ini setara pula dengan 'mask' sebuah bentuk, dan sering dipakai bukan hanya sebagai masukan "-shade", melainkan juga untuk Menggunakan mask pada gambar guna memotong bentuk yang sama dari hasil yang sudah di-shade. Lihat Memberi mask pada bentuk ter-shade di bawah. Bagi operator "-shade", gambar ini akan tampak seperti dataran hitam yang datar, dengan sebuah plato putih datar yang menjulang tegak ke atas. Karena itu hanya tepi gambar inilah yang menghasilkan efek menarik. Untuk efek itu, kedua argumennya menentukan arah datangnya cahaya. Argumen pertama adalah direction , arah asal cahaya. Jadi sudut '0' derajat berarti dari timur (atau kiri), '90' berlawanan arah jarum jam dari utara (atau atas), dan seterusnya. Sebagai contoh...

  magick shade_a_mask.gif   -shade    0x45   shade_direction_0.gif
  magick shade_a_mask.gif   -shade   45x45   shade_direction_45.gif
  magick shade_a_mask.gif   -shade   90x45   shade_direction_90.gif
  magick shade_a_mask.gif   -shade  135x45   shade_direction_135.gif
  magick shade_a_mask.gif   -shade  180x45   shade_direction_180.gif

Anda sudah menangkap idenya. Cahaya bisa datang dari arah mana saja. Argumen yang lain adalah elevation , dan mewakili sudut yang dibentuk sumber cahaya terhadap tanah. Bayangkan saja seberapa tinggi matahari di siang hari, sehingga '0' adalah fajar dan '90' tepat di atas kepala.

[diagram]

  magick shade_a_mask.gif   -shade  90x0    shade_elevation_0.gif
  magick shade_a_mask.gif   -shade  90x15   shade_elevation_15.gif
  magick shade_a_mask.gif   -shade  90x30   shade_elevation_30.gif
  magick shade_a_mask.gif   -shade  90x45   shade_elevation_45.gif
  magick shade_a_mask.gif   -shade  90x60   shade_elevation_60.gif
  magick shade_a_mask.gif   -shade  90x75   shade_elevation_75.gif
  magick shade_a_mask.gif   -shade  90x90   shade_elevation_90.gif

Seperti terlihat, dengan elevation '0' bentuknya hanya di-highlight pada sisi tempat cahaya datang. Sisanya hitam, karena tak ada cahaya yang jatuh ke permukaan lain. Saya menyebutnya 'Dawn Highlight' dan ini punya kegunaan khusus tersendiri. Ini membawa kita ke catatan pertama. Gambar hasil "-shade" sering punya lebih banyak area gelap atau berbayang daripada area yang di-highlight. Shading-nya tidak seimbang. Semakin tinggi cahaya di atas gambar 'height field', keseluruhan gambar akan makin memutih, sampai pada 'tengah hari' atau elevation '90' semua area datar menjadi putih cemerlang, dan hanya lereng serta tepi yang ter-shade menjadi abu-abu, dengan abu-abu pertengahan sebagai maksimum, atau perubahan lereng yang 'seperti tebing'. Gambar 'tengah hari' ini adalah kasus khusus lain yang mirip sistem deteksi tepi, meskipun lebarnya antara 2 dan 4 piksel untuk tepi yang tajam. Dulu saya memakai gambar ini untuk membuat mask bagi tepi bevel gambar "-shade", supaya area datarnya menjadi transparan. Bila sudut elevation melewati '90' derajat, hasilnya sama seperti cahaya datang dari arah sebaliknya. Jadi argumen '0x135' akan menghasilkan hasil yang persis sama dengan '180x45'. Sudut elevation negatif juga memberi hasil yang sama, seolah cahaya datang dari bawah, ke permukaan yang 'tembus cahaya'. Jadi '0x-45' sama dengan '0x45'. Dengan kata lain, untuk sebuah shade tertentu biasanya ada 4 argumen lain yang menghasilkan hasil yang sama juga. Dari semua itu saya menganggap argumen '120x45' paling pas untuk pemakaian langsung keluaran shade. Sebagai contoh, di sini argumen itu membuat teks ber-bevel...

  magick -size 320x100 xc:black \
          -font Candice -pointsize 72 -fill white \
          -draw "text 25,65 'Anthony'" \
          -shade 120x45  shade_anthony.jpg

[IM Output]

Salah satu masalah besar "-shade" adalah ketebalan bevel yang sebenarnya dihasilkan. Tepi tajam seperti yang saya pakai di atas selalu menghasilkan bevel selebar sekitar 4 piksel, ke dalam maupun ke luar area yang di-mask. Tidak ada cara untuk mengatur ketebalan ini, kecuali mengubah ukuran gambar sebelum dan sesudah memakai operator "-shade".. Bila Anda ingin tahu seberapa terang 'area datar' pada sudut pencahayaan elevation tertentu, gunakan perintah berikut untuk mem-shade permukaan berwarna polos yang datar.

  magick -size 50x50 xc:white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 0x45   -gravity center -crop 1x1+0+0 txt:-

[IM Text]

Seperti terlihat, elevation '45' derajat menghasilkan warna datar yang cukup terang, sekitar abu-abu 70%, dan itu tingkat abu-abu yang wajar untuk tampilan umum. Namun bila Anda berencana memakai shade untuk membuat highlight 3-D dari berbagai bentuk, tingkat abu-abu yang sebenarnya menjadi sangat penting. Ini akan dibahas nanti di Membuat highlight overlay. Pada dasarnya, itulah operator "-shade". Namun memakainya secara efektif membuka serangkaian teknik dan kemungkinan, yang akan kita lihat berikutnya.

Memberi mask pada bentuk ter-shade

Seperti disebut di atas, sebuah bentuk 'mask' sederhana sering dipakai bersama "-shade" untuk menghasilkan efek 3-D yang rumit dari bentuk yang sederhana. Sebagai contoh, mari kita lakukan itu pada gambar mask yang di-shade langsung.

  magick shade_direction_135.gif  shade_a_mask.gif \
          -alpha Off -compose CopyOpacity -composite   shade_beveled.png

[IM Output] [IM Output] [IM Output]

Perhatikan bahwa sekitar separuh bevel yang dihasilkan operator "-shade" sebenarnya jatuh di luar area yang di-mask. Dengan kata lain, bevel yang lurus terpotong separuh ketika di-mask. Sebaliknya, gambar shade tegak atau 'tengah hari' (memakai sudut elevation '90' derajat) bisa dipakai untuk mengambil tepi bevel-nya saja, sehingga bagian tengah gambar menjadi berongga.

  magick shade_direction_135.gif \
          \( shade_elevation_90.gif -normalize -negate \) \
          -alpha Off -compose CopyOpacity -composite   shade_beveled_edge.png

[IM Output] [IM Output] [IM Output]

Perhatikan bahwa gambar shade 'tengah hari' ini, meski menyediakan cara untuk mem-mask lokasi (dan intensitas) efek operator "-shade", sebenarnya tidak menutupi efek itu sepenuhnya. Dengan menggabungkan gambar shade 'tengah hari' tadi dengan mask aslinya, ukuran mask itu dapat sedikit diperbesar sehingga menghasilkan gambar ber-bevel yang di-mask dengan lebih baik. [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
|

  magick shade_direction_135.gif \
          \( shade_elevation_90.gif -normalize -negate \
             shade_a_mask.gif -compose screen -composite \) \
          -alpha Off -compose CopyOpacity -composite   shade_beveled_plus.png

[IM Output]
Ingat, dengan IM v6 Anda bisa membuat gambar 'shade' yang tadi saya buat itu di dalam satu perintah yang sama. Jadi contoh di atas bisa dibuat sepenuhnya dari nol. Sebagai contoh. |

  magick -font Candice -pointsize 72 -background black -fill white \
          label:X  -trim +repage -bordercolor black -border 10x5 \
          \( -clone 0 -shade  135x45 \) \
          \( -clone 0 -shade  0x90  -normalize -negate \
             -clone 0 -compose screen -composite \) \
          -delete 0 -alpha Off -compose CopyOpacity -composite \
          shade_beveled_X.png

[IM Output]

Gambar bentuk ter-shade

Operator Alpha Extract tidak hanya mengekstrak kanal alpha dari gambar berbentuk sebagai mask grayscale, tetapi juga punya efek samping mempertahankan bentuk itu di dalam kanal alpha yang 'dimatikan'. Karena 'dimatikan', kanal itu tidak akan disentuh banyak operator pemrosesan gambar, termasuk "-shade", sehingga detailnya terjaga. Artinya, untuk gambar berbentuk, Anda dapat mengekstrak bentuknya, mengerjakan pekerjaannya, lalu memulihkan transparansinya SETELAH semua pemrosesan gambar selesai, cukup dengan menyalakan Alpha On lagi! Sebagai contoh, di sini saya menggambar sebuah 'Heart' di atas latar belakang transparan, mem-blur dan mem-shade gambarnya sedikit, lalu memulihkan garis luar bentuk aslinya. |

  magick -size 100x100 -gravity center -background None \
          -font WebDings label:Y \
          -alpha Extract -blur 0x6 -shade 120x21 -alpha On \
          -normalize +level 15%  -fill Red -tint 100%    shade_heart.png

[IM Output]
Yang bisa saya katakan hanyalah WOW, hemat waktu sekali! Jauh lebih sederhana daripada perintah sebelumnya dengan segala pemrosesan tambahan dan penggandaan gambarnya.

Membulatkan tepi Shade

Seperti Anda lihat pada contoh terakhir, dengan mem-blur mask bentuk gambar, 'lereng' pada 'tebing' tepi akan dihaluskan, seakan terkikis waktu. Ini menghasilkan efek membulat yang bagus pada gambar shade.

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          shade_circle_mask.gif
  magick shade_circle_mask.gif            -shade 120x45  shade_blur_0.gif
  magick shade_circle_mask.gif -blur 0x1  -shade 120x45  shade_blur_1.gif
  magick shade_circle_mask.gif -blur 0x2  -shade 120x45  shade_blur_2.gif
  magick shade_circle_mask.gif -blur 0x3  -shade 120x45  shade_blur_3.gif
  magick shade_circle_mask.gif -blur 0x4  -shade 120x45  shade_blur_4.gif
  magick shade_circle_mask.gif -blur 0x5  -shade 120x45  shade_blur_5.gif

Seperti terlihat, blur tidak hanya membulatkan tepi, tetapi juga membuat efek pencahayaannya lebih redup. Kontras hasilnya dapat dimaksimalkan dengan menormalkannya, sehingga titik paling terang dan paling gelap kembali ke warna putih dan hitam murni.

  magick shade_blur_3.gif   -normalize  shade_blur_3n.gif

[IM Output] [IM Output]

Satu-satunya kelemahannya, cara ini umumnya juga menggelapkan gambar yang di-shade. Hal ini perlu kita perhitungkan di Membuat highlight overlay. Mari kita selesaikan gambar shade ini dengan mem-mask-nya secara langsung juga..

  magick shade_blur_3n.gif shade_circle_mask.gif \
          -alpha Off -compose CopyOpacity -composite   shade_blur_3n_mask.png

[IM Output] [IM Output]

Seperti terlihat, mem-blur gambar mask akan membulatkan tepi bentuk hasilnya dengan sangat rapi.

Membuat highlight overlay

Keluaran operator "-shade" memang bagus, tetapi jarang sekali yang benar-benar Anda inginkan berupa gambar grayscale polos dari bentuk Anda. Yang dibutuhkan adalah warna. Namun ini tidak semudah kelihatannya, karena dua cara utama menambahkan warna, yaitu memberi tint pada warna nada tengah untuk sekadar mewarnai ulang grayscale, atau komposisi alpha 'Overlay' untuk mengganti area abu-abu dengan sebuah gambar, sama-sama bergantung pada bentuk khusus gambar grayscale. Yaitu, abu-abu nada tengah yang sempurna ('grey50') diganti oleh warna atau gambar tersebut, sementara abu-abu yang lebih putih atau lebih gelap akan memutihkan dan menggelapkan warna atau gambar itu sebagaimana mestinya. Gambar grayscale 'highlight overlay' khusus dengan abu-abu nada tengah yang sempurna untuk area yang tidak diubah ini tidak terlalu mudah dibuat memakai "-shade". Namun berikut ini beberapa cara paling sederhana yang saya temukan. Memakai sudut pencahayaan elevation 30 derajat pada "-shade" adalah salah satu cara menghasilkan abu-abu nada tengah yang sempurna untuk area datar pada bentuk yang di-shade. Sebagai contoh, di sini saya mem-shade sebuah gambar, lalu mengambil piksel kiri-atasnya untuk memeriksa warna hasil pada bagian 'datar' gambar itu. [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
| |

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 120x30           shade_30.png
  magick shade_30.png   -gravity center -crop 1x1+0+0 txt:-

[IM Image]
| [IM Text]
Sayangnya, mengubah efek pembulatan "-blur" pada perintah di atas cenderung ikut mengubah intensitas highlight gambar shade hasilnya. Artinya, blur yang besar tidak hanya menghasilkan tepi yang tampak membulat rapi, tetapi juga membuat highlight-nya begitu redup sampai nyaris tak terlihat. Ini berarti Anda perlu menambahkan jauh lebih banyak kontras pada keluaran gambar "-shade" yang dihasilkan, agar highlight-nya efektif sebagai gambar overlay. Untuk mengatasinya kita perlu cara menghilangkan efek kontras dari penyetelan pembulatan itu. Cara yang lazim adalah sekadar me-"-normalize" gambarnya, tetapi bila itu dilakukan pada gambar shade 30 derajat, hasilnya area 'datar' tidak lagi berupa abu-abu yang sempurna. Sebagai contoh... | |

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 120x30 -normalize   shade_30_norm.png
  magick shade_30_norm.png   -gravity center -crop 1x1+0+0 txt:-

[IM Image]
| [IM Text]
Setelah bereksperimen lebih jauh, saya menemukan bahwa memakai sudut elevation shade 21.78 derajat, setelah dinormalkan, menghasilkan tingkat abu-abu nada tengah sempurna yang diinginkan sekaligus efek highlight yang kuat. | |

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 120x21.78 -normalize   shade_21_norm.png
  magick shade_21_norm.png   -gravity center -crop 1x1+0+0 txt:-

[IM Image]
| [IM Text]
Karena gambar shade kini dijalankan melalui operator "-normalize", nilai "-blur" yang dipakai untuk 'membulatkan tepi' tidak lagi memengaruhi intensitas akhir hasilnya. Metode yang jauh lebih baik. Ringkasnya, menormalkan sebuah gambar shade akan menggeser nada tengahnya menjauh dari warna abu-abu yang sempurna. Sekarang kita dapat menyetel intensitas keluaran highlight yang dihasilkan sepenuhnya terlepas dari penyetelan yang lain. Karena hasil yang dinormalkan biasanya ekstrem, kita perlu de-normalisasi yang terkendali, atau kendali anti-kontras, untuk menurunkan highlight ke tingkat yang diinginkan. Cara paling sederhana untuk menyetel highlight hasilnya adalah memberi tint warna pada gambar dengan abu-abu yang sempurna. Ini akan menggeser semua tingkat warna dalam gambar ke arah warna abu-abu nada tengah murni di pusat. Sebagai contoh...

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          \( +clone -blur 0x2 -shade 120x21.78 -normalize  \) \
          +swap -alpha Off -compose CopyOpacity -composite  shade_tint_0.png
  magick shade_tint_0.png -fill grey50  -colorize 10%  shade_tint_10.png
  magick shade_tint_0.png -fill grey50  -colorize 30%  shade_tint_30.png
  magick shade_tint_0.png -fill grey50  -colorize 50%  shade_tint_50.png
  magick shade_tint_0.png -fill grey50  -colorize 80%  shade_tint_80.png

Alternatif selain sekadar memberi tint linear pada highlight adalah mengurangi efek umumnya sambil mempertahankan titik terang/gelap yang ekstrem, yaitu dengan memakai kontras sigmoidal non-linear. Cara ini semestinya memberi tampilan yang lebih 'alami' pada efek highlight, dan dapat membuat highlight lebih terang, seolah permukaannya lebih memantulkan cahaya. Namun agar teknik ini lebih efektif, kita perlu memastikan tidak ada warna putih dan hitam murni pada hasil shade. Ini dapat dicapai dengan lebih dulu memakai "-contrast-stretch" sebesar '0%' alih-alih "-normalize", lalu men-de-normalisasi hasilnya sedikit, seperti yang kita lakukan di atas. Ini mungkin tampak sekadar menambah kerumitan pembuatan gambar highlight overlay, tetapi menonjolkan titik-titik terang pada highlight membuat pemrosesan tambahan itu sepadan. Sebagai contoh...

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          \( +clone -blur 0x2 -shade 120x21.78 -contrast-stretch 0% \) \
          +swap -alpha Off -compose CopyOpacity -composite shade_sig_0.png

  magick shade_sig_0.png  -sigmoidal-contrast 10x50%  shade_sig-10.png
  magick shade_sig_0.png  -sigmoidal-contrast  5x50%  shade_sig-5.png
  magick shade_sig_0.png  -sigmoidal-contrast  2x50%  shade_sig-2.png

  magick shade_sig_0.png  +sigmoidal-contrast  2x50%  shade_sig+2.png
  magick shade_sig_0.png  +sigmoidal-contrast  5x50%  shade_sig+5.png
  magick shade_sig_0.png  +sigmoidal-contrast 10x50%  shade_sig+10.png

Seperti terlihat, highlight secara keseluruhan berkurang intensitasnya, tetapi titik terang dari pantulan cahaya tetap seterang semula, hanya mengecil ukurannya. Hasilnya adalah tampilan 'mengkilap' yang jauh lebih alami pada bentuk itu. Satu-satunya kelemahan teknik ini adalah munculnya 'titik' bayangan juga, meski sering kali tidak begitu kentara. Terakhir, kita dapat memadukan 'titik highlight' dengan pengurangan highlight secara umum untuk menghasilkan satu set kontrol pembangkit highlight overlay yang sangat mudah diatur... [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
|

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          \( +clone -blur 0x4 -shade 120x21.78 -contrast-stretch 0% \
             +sigmoidal-contrast 7x50% -fill grey50 -colorize 10%  \) \
          +swap -alpha Off -compose CopyOpacity -composite shade_overlay.png

[IM Output]

Ringkasnya, contoh di atas punya empat kontrol terpisah...
"blur" : Membulatkan tepi bentuk (0.001=ber-bevel 2=dihaluskan 10=dibulatkan)
"shade" : Arah datangnya cahaya (120=kiri-atas 60=kanan-atas)
"sigmoidal" : kendali pantulan permukaan pada titik highlight (1=datar 5=bagus 10=memantul )
"colorize" : Kontras keseluruhan highlight ( 0%=terang 10%=bagus 50%=redup )

Perhatikan, meski contoh di atas sudah dibentuk mengikuti bentuk 'circle' aslinya, transparansi sebaiknya baru dipulihkan SETELAH komposisi 'Overlay' diterapkan, bukan sebelumnya. Selain itu, bila Anda berencana memakai sebuah highlight berulang kali pada bentuk yang sama (setelah rotasi apa pun dilakukan), highlight overlay itu dapat dibuat sekali di muka untuk setiap bentuk yang akan dipakai, lalu hasilnya disimpan untuk dipakai berkali-kali. Contoh pemakaian ulang overlay shading semacam ini ada pada pembuatan sampul DVD 3D dari gambar sumber yang datar di Forum Diskusi IM. Saya juga sangat menyarankan Anda bereksperimen dengan teknik-teknik di atas, karena itulah kuncinya agar gambar berbentuk yang datar tampak jauh lebih nyata. Bila Anda punya ide lain untuk highlighting, beri tahu saya.

FUTURE:
   Color Tinting the Overlay image
   Overlay Alpha Composition with an Image

Menggunakan highlight Dawn Shade

Di Memberi mask pada bentuk ter-shade di atas kita sudah melihat betapa bergunanya gambar shade 'tengah hari' (memakai elevation '90') untuk mem-mask lokasi dan luas efek yang dihasilkan "-shade". Namun gambar shade mendatar atau 'fajar' (memakai elevation '0') dari sebuah bentuk juga bisa sangat berguna. Gambar itu misalnya dapat dipakai sebagai mask bagi gambar putih atau hitam untuk menghasilkan efek highlight dan shading yang terpisah pada sebuah bentuk. Cara ini juga dapat dipakai untuk memastikan sebuah bentuk mendapat area terang dan gelap yang kurang lebih sama banyak (atau bahkan sengaja tidak sama), karena saya membuat keduanya secara terpisah tetapi dengan kendali penuh.

FUTURE: more detail here

Lihat Logo 3-D lanjutan yang pertama untuk contoh pemakaian teknik ini.


Menggunakan FX, operator gambar rakitan sendiri Operator daftar gambar "-fx" adalah operator rakitan-sendiri serba guna yang tidak masuk ke kategori operator IM mana pun, karena dapat dipakai untuk membuat hampir semua operasi gambar. Contoh pemakaiannya tersebar di seluruh halaman ini, tetapi di sini kita akan melihat khusus kemampuannya dan cara Anda memanfaatkannya. Perintah ini begitu umum kemampuannya sehingga bisa,

  • membuat kanvas, gradien, dan colormap matematis.
  • memindahkan nilai warna antar gambar dan antar kanal.
  • menyetel warna gambar dengan cara apa pun yang terbayangkan
  • menggeser, membalik, mencerminkan, memutar, menskalakan, menggunting, dan umumnya mendistorsi gambar.
  • menggabungkan atau mengomposisikan beberapa gambar sekaligus.
  • menyusun gambar sebagai tile dengan cara yang aneh dan menakjubkan.
  • mengonvolusi atau menggabungkan piksel-piksel bertetangga.
  • menghasilkan metrik atau 'sidik jari' gambar
  • membandingkan gambar dengan cara yang tidak biasa.

Tentu saja banyak dari teknik ini sudah menjadi bagian IM, dengan hasil yang lebih cepat dan lebih lentur. Tetapi bila belum tersedia secara bawaan, "-fx" memungkinkan Anda membuat versi sendiri dari operasi yang diinginkan. Nyatanya saya dan yang lain sering memakainya untuk membuat prototipe operasi baru yang kemudian ditanamkan ke pustaka inti IM. Sebagai contoh lihat DIY New Ordered Dither Replacement, tempat saya memakai "-fx" untuk mengembangkan versi revisi operator -ordered-dither". Pada dasarnya operator ini memungkinkan Anda melakukan operasi matematis bebas pada satu gambar atau lebih. Untuk ringkasan resmi perintah ini lihat FX, The Special Effects Image Operator di Situs Web ImageMagick.

Penggunaan dasar FX

Perintah ini menerima rangkaian gambar sebanyak yang Anda mau. Biasanya satu atau dua gambar, lalu mengganti SEMUA gambar masukan dengan salinan gambar pertama yang telah dimodifikasi oleh hasil fungsi "-fx". Artinya, metadata apa pun yang ada pada gambar pertama akan dipertahankan pada hasil operator "-fx".Demi kemudahan matematis, semua nilai warna yang diberikan dinormalkan ke rentang 0.0 sampai 1.0. Hasilnya pun diharapkan berada dalam rentang itu. Termasuk kanal transparansi atau alpha, yang berkisar dari 0.0 (berarti transparan penuh) sampai 1.0 (berarti opak penuh). Nilai-nilai ini mewakili 'transparansi alpha' dan sebenarnya kebalikan dari cara IM biasanya menyimpan transparansi secara internal (sebagai nilai matte). Namun bentuk ini lebih benar secara matematis dan lebih mudah dipakai. Pengaturan "-channel" menentukan kanal mana pada gambar pertama (disebut juga gambar 'ke-nol' atau "u") yang diganti dengan hasil operator "-fx". Secara bawaan ini terbatas pada kanal warna ('RGB') gambar aslinya saja. Transparansi yang sudah ada pada gambar itu tidak akan diubah, kecuali pengaturan "-channel" diubah agar menyertakan kanal alpha ('A'). Ekspresi dijalankan sekali untuk setiap piksel, dan sekali pula untuk setiap kanal warna pada piksel yang sedang diproses. Karena ekspresinya juga diurai ulang setiap kali dijalankan, ekspresi yang rumit bisa makan waktu pada gambar besar. Sebagai contoh, di sini kita mendefinisikan gambar hitam, lalu menyetel kanal birunya menjadi separuh terang sehingga terbentuk warna 'navy blue'. |

  magick -size 64x64 xc:black -channel blue -fx '1/2' fx_navy.gif

[IM Output]
Dan di sini kita mengambil gradien hitam-putih, lalu menyetel kanal biru dan hijaunya menjadi nol, sehingga menjadi gradien hitam-merah. |

  magick -size 64x64 gradient:black-white \
           -channel blue,green    -fx '0'    fx_red.gif

[IM Output]
| _Agar pengaturan "-channel" lebih mirip operator "-fx", pengaturan itu menerima kombinasi huruf apa pun dari 'RGBA' untuk menyebutkan kanal yang menjadi batas kerja operator.

Artinya, untuk membatasi keluaran "-fx" hanya pada kanal biru dan hijau, kini Anda cukup menulis "-channel BG" alih-alih "-channel blue,green" yang lebih panjang._
Kita bisa saja membuat contoh-contoh di atas tanpa "-fx", tetapi kemampuan melakukannya pada gambar yang sudah ada itulah yang membuatnya menjadi operator gambar yang kuat. Fungsi ini sebenarnya dapat membaca dan memakai piksel APA PUN, atau warna tertentu, dari gambar MANA PUN yang sudah ada dalam rangkaian gambar di memori. Gambar pertama, si 'nol', diberi nama khusus "u". Gambar kedua "v". Gambar lain di memori dapat dirujuk lewat indeks. Jadi "u[3]" adalah gambar keempat dalam rangkaian gambar saat ini, sedangkan "u[-1]" adalah gambar terakhir dalam rangkaian itu. Skema indeks ini sama dengan yang dipakai operator daftar gambar, jadi Anda pasti sudah terbiasa. Bila tidak ada penjelas lain, nilai warna yang dipakai adalah warna yang sama pada gambar yang disebutkan. Artinya, kecuali Anda menyatakan secara khusus ingin memakai warna merah, yang dipakai adalah nilai warna untuk kanal warna yang sedang diproses perintah itu saat itu. Jadi, ekspresi akan diterapkan pada nilai warna biru ketika kanal biru sedang diproses. Kecuali diperintahkan lain, IM akan memproses masing-masing nilai warna RGB (sesuai pengaturan "-channel" bawaan) untuk setiap piksel dalam gambar. Artinya, 3wh perhitungan yang mengubah semua nilai dalam gambar dengan ekspresi yang diberikan. Sebagai contoh, di sini kita mengambil gambar bawaan IM "rose:" lalu mengalikan semua nilai pikselnya dengan 50%. |

  magick rose: -fx 'u*1.5'    fx_rose_brighten.gif

[IM Output]
Pada contoh di atas, masing-masing nilai merah, hijau, dan biru dikalikan 1.5. Bila nilai hasilnya di luar rentang 0 sampai 1, nilai itu akan dibatasi ke batas yang sesuai (1.0 dalam hal ini), kecuali Anda memakai versi HDRI ImageMagick yang bawaan. Banyak rumus "-fx" lain untuk mewarnai ulang gambar dibahas di Penyesuaian warna matematis dan Kurva histogram. Karena kita juga dapat merujuk gambar mana pun dalam rangkaian gambar saat ini sebagai bagian dari ekspresi untuk memodifikasi gambar pertama, kita bisa menggabungkan dua gambar, atau bahkan lebih, dengan cara apa pun yang kita mau. Di sini kita membuat gambar bagan warna hitam-merah-biru, dengan menyalin kanal biru dari gradien hitam-biru (yang diputar) ke dalam gradien hitam-merah yang kita buat di atas tadi.

  magick -size 64x64 gradient:black-blue -rotate -90  fx_blue.gif
  magick fx_red.gif  fx_blue.gif \
          -channel B  -fx 'v'    fx_combine.gif

[IM Output] [IM Output] [IM Output]

| _Tentu saja kita bisa saja memakaimetode komposisi penyalinan kanal yang jauh lebih cepat. Tetapi bukan itu intinya.

Meski kebalikannya juga benar. Hampir setiap operasi gambar IM dapat digantikan oleh fungsi FX yang setara.

_
Nah, gambar kedua pada contoh di atas hanya dipakai sebagai gambar sumber. Yang sebenarnya terjadi, "-fx" lebih dulu membuat salinan gambar pertama saja. Salinan itu lalu dimodifikasi menurut rumusnya, dengan memakai semua gambar lain yang diberikan. Dan akhirnya semua gambar masukan dibuang, digantikan oleh salinan gambar pertama yang sudah dimodifikasi tadi. Anda juga dapat menghitung nilai berdasarkan posisi tiap piksel di dalam gambar. Nilai 'i,j' adalah posisi piksel yang sedang diproses, sedangkan 'w,h' memberikan ukuran gambar (gambar pertama, kecuali ada penjelas gambar tertentu). Sebagai contoh, di sini kita membuat gambar gradien rakitan sendiri. |

  magick rose: -channel G -fx 'sin(pi*i/w)' -separate   fx_sine_gradient.gif

[IM Output]
Atau sesuatu yang lebih rumit memakai kedua nilai posisi 'i,j'. |

  magick -size 80x80 xc: -channel G -fx  'sin((i-w/2)*(j-h/2)/w)/2+.5'\
          -separate fx_2d_gradient.gif

[IM Output]
Ketika membuat gradien grayscale, operator -fx dapat dibuat sekitar 3 kali lebih cepat, cukup dengan memintanya memproses satu kanal warna saja, misalnya kanal 'G' atau hijau pada contoh di atas. Kanal itu lalu dapat dipisahkan untuk menghasilkan gambar grayscale akhirnya. Ini bisa memberi lonjakan kecepatan yang sangat besar, terutama bila rumus "-fx" yang dipakai sangat rumit. Untuk gradien hasil FX lainnya, lihat contoh Meracik gradien sendiri. Informasi posisi dapat Anda pakai untuk mencari piksel tertentu dari gambar sumber memakai sintaksis 'p{x,y}'. Sebagai contoh, Anda dapat dengan mudah membuat fungsi 'gambar cermin' sendiri (seperti operator gambar "-flop"), yang mengganti setiap piksel dengan nilai warna dari posisi 'cermin' pada sumber aslinya. |

  magick rose: -fx  'p{w-i-1,j}'  fx_rose_mirror.gif

[IM Output]
Jenis 'distorsi gambar' ini menjadi lebih kuat dengan dibuatnya pemetaan gambar distorsi, atau jenis tabel pencarian nilai lain, dalam bentuk gambar. Contoh melakukannya sudah disediakan di Pola dither dan peta ambang batas rakitan sendiri, tempat FX dipakai untuk mengganti warna tertentu dengan pola dari gambar lain. Nah, ukuran gambar akhir yang dihasilkan sebuah ekspresi FX sama dengan gambar pertama yang diberikan, jadi untuk menghasilkan gambar yang lebih besar, Anda perlu menyetel gambar pertama ke ukuran yang diinginkan. Dalam situasi semacam ini, gambar kedua (atau bahkan ketiga) dapat dipakai sebagai sumber warna (karena itulah ada Swap pada contoh berikut). Sebagai contoh, di sini kita mengubah ukuran gambar rose (memakai Interpolative Resize) untuk menghasilkan gambar yang lebih besar. |

  magick rose:  -size 120x80 xc: +swap  \
           -fx 'v.p{  (i+.5)*v.w/w-.5, (j+.5)*v.h/h-.5  }' \
           fx_scaled.png

[IM Output]
Perhatikan bagaimana pencarian pikselnya dilakukan; mungkin tampak rumit, tetapi itulah cara yang benar untuk menskalakan (mendistorsi) sebuah gambar. Pada dasarnya semua tambahan nilai '0.5' dalam ekspresi itu diperlukan agar konversi antara koordinat piksel yang dipakai untuk koordinat masukan 'i,j' dan pencarian lokasi 'v.p{...} berlangsung benar, sementara koordinat gambar yang lebih benar secara matematis diperlukan untuk perhitungan matematisnya sendiri (penskalaan). Cara di atas sebenarnya persis metodologi yang dipakai segala bentuk distorsi gambar. Anda dapat melihat padanan FX ini untuk sebagian besar distorsi dengan menyalakan ringkasan distorsi verbose. Fasilitas itu melaporkan padanan FX untuk sebagian besar distorsi gambar, sebagai cara memeriksa ulang bahwa distorsinya bekerja seperti yang diharapkan. Pemakaian operator rakitan sendiri FX untuk mendistorsi gambar menunjukkan betapa kuatnya operator ini sebenarnya. Kalau bukan karena operator ini, saya ragu banyak operasi baru seperti distorsi, sparse-color, atau ordered dither akan ditambahkan ke Pustaka Inti ImageMagick. Berikut sesuatu yang sedikit lebih sederhana, menukar kanal merah dan biru gambar rose. Coba cari tahu cara kerjanya. |

  magick rose: \( +clone -channel R -fx B \) \
          +swap -channel B -fx v.R     fx_rb_swap.gif

[IM Output]
| _Cara yang lebih cepat dan lebih baik untuk melakukan hal yang sama adalah memakai "-separate" dan "-combine"). Lihat Menggabungkan gambar kanal RGB. Sebagai alternatif Anda juga dapat memakai "-color-matrix" untuk melakukan hal yang sama dengan lebih cepat lagi.

Anda melihat polanya, bukan?_
Karena pengaturan "-channel" bawaan membatasi keluaran operator "-fx" hanya pada tiga kanal warna, bila Anda ingin memengaruhi kanal alpha atau transparansi, kanal itu harus disebutkan secara eksplisit dengan mengubah pengaturan channel. Sebagai contoh, mari kita buat gambar "rose:" yang semitransparan, dengan menyetel semua nilai kanal alpha menjadi separuh. |

  magick rose: -alpha set  -channel A  -fx '0.5'    fx_rose_trans.png

[IM Output]
Perhatikan, agar contoh di atas bekerja dengan benar saya perlu memastikan "rose:" benar-benar punya kanal alpha yang bisa dipakai "-fx". Saya melakukannya dengan operator kendali kanal alpha. Kemampuan operator "-fx" memanipulasi kanal RGBA sebuah gambar membuatnya sempurna untuk memanipulasi kanal dan mask.
Sejak IM 6.2.10 Anda dapat menambahkan penetapan variabel ke dalam ekspresi "-fx", sehingga kerumitan sebagian ekspresi dapat dikurangi, yang pada dasarnya mustahil dilakukan dengan cara lain. Sebagai contoh, di sini saya membuat gradien berdasarkan jarak dari sebuah titik tertentu (yang ditetapkan ke variabel 'xx' dan 'yy'). Tanpa variabel, rumus ini bisa jadi sangat sulit dibaca. |

  magick -size 100x100 xc:  -channel G \
          -fx 'xx=i-w/2; yy=j-h/2; rr=hypot(xx,yy); (.5-rr/70)*1.2+.5' \
          -separate  fx_radial_gradient.png

[IM Output]
| Karena penanganan tokenisasi yang dipakai "-fx" sederhana, nama variabel hanya boleh terdiri atas huruf dan tidak boleh mengandung angka. Selain itu, karena banyak huruf tunggal dipakai sebagai variabel internal untuk mengakses informasi gambar, disarankan nama variabel panjangnya minimal dua huruf. Karena itu saya memakai 'xx' dan 'yy' alih-alih sekadar 'x' atau 'y'.
| _Fungsi "-fx" 'rr=hypot(xx,yy)' ditambahkan pada IM v6.3.6 untuk mempercepat ekspresi yang sangat sering dipakai, 'rr=sqrt(xx*xx+yy*yy)'.

Tentu saja bila yang Anda perlukan adalah jarak kuadrat, sebaiknya hindari fungsi 'hypot()' beserta fungsi sqrt() yang tersirat di dalamnya._
Untuk contoh ekspresi yang benar-benar rumit, lihat Gradien rakitan sendiri yang lebih kompleks, yang mustahil dibuat tanpa penetapan banyak pernyataan. Hal yang sama berlaku untuk bentuk FX dari distorsi perspektif. Sejak IM versi 6.3.0-1, kerumitan ekspresi "-fx" mulai menuntut file eksternal, jadi kini bentuk baku '@_filename_' dapat dipakai untuk membaca ekspresi dari sebuah file. |

   echo "u*2" | magick rose: -fx "@-"  fx_file.png

[IM Output]
Ini juga berarti Anda dapat memakai skrip yang lebih rumit untuk menghasilkan ekspresi FX tertentu bagi pekerjaan tertentu. Secara internal file itu sekadar dibaca menjadi sebuah string lalu ditafsirkan seperti biasa. Pengaturan lain yang penting bagi "-fx" adalah "-virtual-pixel" dan "-interpolate". Pengaturan piksel virtual memungkinkan kita menentukan warna atau hasil gambar apa yang harus dikembalikan ketika koordinat pencarian jatuh di luar area yang dicakup gambar masukan. Dengan begitu kita dapat menetapkan efek tepi untuk hal seperti blur, sekaligus menyusun gambar sebagai tile pada area yang lebih luas. Pengaturan interpolasi memungkinkan kita menentukan bagaimana IM mencampur warna piksel bertetangga ketika koordinat pencarian (nilai floating point) jatuh di antara koordinat bilangan bulat piksel pada gambar masukan. Untuk keterangan lebih lanjut lihat pencarian piksel terinterpolasi. | Beberapa fungsi lain ditambahkan pada berbagai waktu
IM v6.3.6 : hypot()
IM v6.7.3-4 : while(), not(), guass(), squish()

Debugging FX

'debug(_expr_)' pada dasarnya adalah cara mencetak sebuah nilai floating point setiap kali ekspresi FX dihitung. Ini pada gilirannya menjadi metode untuk men-debug ekspresi Anda. Namun keluaran "debug()" dapat dibatasi dengan memakai ekspresi if-else terner. Sebagai contoh, perintah berikut akan mencetak nilai warna floating point untuk piksel 10,10 dari gambar bawaan "rose:". Hasil gambarnya sendiri diabaikan dengan memakai penangan gambar 'NULL:'. |

  magick rose: -fx 'i==10&&j==10?debug(u):1; u' null:

[IM Output]
Ingat, keluarannya ada pada standard error, bukan standard output biasa, sehingga Anda dapat memakainya di dalam pipeline perintah tanpa masalah. Perhatikan bagaimana ekspresi FX dijalankan tiga kali, sekali untuk setiap kanal, hanya untuk satu piksel itu. Kalikan dengan jumlah piksel, dan Anda bisa membayangkan panjang keluarannya seandainya "debug()" tidak dibatasi hanya pada satu piksel, bahkan untuk gambar sekecil ini.

Operasi bawaan mirip FX

Operator -fx mewakili cara mengembangkan fungsi pemrosesan gambar baru yang sebelumnya tidak ada di ImageMagick. Hasil pengembangan semacam itu oleh para pengguna telah membuat ImageMagick tumbuh, dengan fungsi dan metode baru seperti tabel pencarian warna ("-clut"). Namun umumnya, begitu sebuah metode baru stabil dengan "-fx", ekspresinya diubah menjadi operasi bawaan yang lebih cepat, biasanya ditambahkan sebagai bagian dari sekelompok operator sejenis. Ini mencakup operator gambar umum berikut beserta metodenya... -evaluate | Fungsi pengubah piksel, nilai warna, dan kanal secara langsung.
(Lihat Evaluate di bawah).
-function | Fungsi pengubah piksel, nilai warna, dan kanal yang lebih rumit.
(Lihat Function di bawah).
-evaluate-sequence | Menggabungkan rangkaian banyak gambar secara matematis
(Lihat Evaluate-Sequence di bawah).
-sparse-color | Operator pewarnaan ulang gambar serba guna.
(Lihat Gradien sparse color )
-compose | Metode penggabungan dan overlay banyak gambar serba guna.
(Lihat Komposisi alpha).
-distort | Operator distorsi gambar serba guna, memakai pemetaan piksel terbalik.
(Lihat Operator Distort )
-morphology | Fungsi konvolusi/morfologi efek area serba guna.
(Lihat Operator Morphology dan Operator Convolve )
Ketika orang mengembangkan jenis operasi gambar baru, biasanya mereka membuat prototipenya dulu memakai operator "-fx". Setelah rampung, 'metode' itu diubah menjadi operator bawaan super cepat di dalam pustaka inti ImageMagick. Pengguna dipersilakan menyumbangkan ekspresi "-fx" sendiri (atau fungsi lain yang mereka definisikan) yang menurut mereka berguna ditambahkan ke IM tetapi belum dicakup operator gambar lain; bila dapat ditangani salah satu operator umum di atas, penambahannya semestinya cukup mudah. Sebagai contoh, saya sendiri memerlukan operasi bertipe 'mask bila warnanya mirip' untuk membandingkan dua gambar. Operasi itu sudah ditambahkan sebagai metode "-compose" baru bernama "ChangeMask". Itu pada gilirannya memungkinkan saya menambahkan optimisasi transparansi yang lebih rumit untuk animasi GIF. Bila kecepatan dan kerumitan "-fx" mulai menjadi masalah, mungkin lebih baik beralih ke bahasa scripting API seperti PerlMagick. Contohnya, PerlMagick "pixel_fx.pl" adalah bagian dari distribusi API tersebut.

Ekspresi FX sebagai escape Format dan Annotate

Sejak IM versi 6.2.10 Anda kini dapat memakai ekspresi FX di dalam string Image Property Escape seperti yang dipakai argumen "-format" dan "-annotate". Urutan escape '%[fx:...]' diganti oleh sebuah angka berupa nilai floating point, yang dihitung sekali untuk setiap gambar dalam rangkaian gambar saat ini. Namun ekspresi FX itu sedikit dimodifikasi selama pemrosesan. Rincinya...

  • Koordinat piksel saat ini 'i', 'j' dipatok ke nilai 0, sehingga variabel gambar dengan sendirinya hanya mengembalikan nilai dari piksel 0,0, kecuali indeks 'p{}' dipakai.
  • Kecuali sebuah kanal warna dipilih, hanya nilai kanal merah yang dikembalikan.
  • Rujukan gambar bawaan 's' disetel ke gambar saat ini, yang sedang dianotasi atau diidentifikasi.
  • Indeks 't' mengembalikan indeks gambar yang dirujuk oleh 's'.

| Sebelum IM v6.6.8-6 kedua nilai ekspresi FX, indeks gambar "t" dan jumlah total gambar "n", rusak dan hanya mengembalikan nilai 0 dan 1 untuk SEMUA gambar. Hal yang sama berlaku bagi persen escape yang setara, '%p' dan '%n'.
Sebagai contoh, di sini saya memakai "-annotate" untuk menuliskan warna sudut kiri atas masing-masing gambar pada gambar itu sendiri. |

  magick -size 150x25 xc:DarkRed xc:Green xc:Blue \
          -fill white -gravity center \
          -annotate 0 '%[fx:t] / %[fx:n] : %[fx:r],%[fx:g],%[fx:b]' \
          annotate_fx_%d.gif

[IM Output] [IM Output] [IM Output]
Perhatikan bagaimana teks yang ditulis berbeda untuk setiap gambar, karena 'r' sebenarnya setara dengan 's.p{0,0}.r'. Begitu pula nilai kanal warna 'g' dan 'b'. Tentu saja masing-masing mengembalikan nilai yang dinormalkan dalam rentang 0.0 sampai 1.0. Agar keluaran nilai warna piksel tertentu lebih mudah, escape '%[pixel:...]' juga ditambahkan pada IM v6.3.0. Operator ini memanggil ekspresi FX yang diberikan sekali untuk setiap kanal pada setiap gambar, lalu memformat nilai yang dikembalikan menjadi warna yang dapat ditangani IM sebagai argumen warna.

  magick -size 300x100 gradient:yellow-limegreen \
          -gravity NorthWest  -annotate 0 '%[pixel:s.p{0,0}]' \
          -gravity Center     -annotate 0 '%[pixel:s.p{0,50}]' \
          -gravity SouthEast  -annotate 0 '%[pixel:s.p{0,99}]' \
          annotate_pixel.gif

[IM Output]

Anda dapat langsung menampilkan hasilnya memakai "-format" bersama perintah "identify". |

  magick identify -format '%[fx:atan(1)*4]' null:

[IM Output]
Perintah ini akan menghitung dan mengembalikan nilai PI secara matematis, meski nilai itu tersedia sebagai variabel bawaan 'pi'. Anda dapat menghasilkan bilangan acak. Misalnya untuk menghasilkan bilangan bulat antara -5 dan 10 inklusif. Di sini saya memakai "info:" yang setara dengan perintah "magick identify". |

  magick xc: -format '%[fx:int(rand()*16)-5]' info:

[IM Output]
Untuk metode lain lihat Alternatif identify: opsi keluaran teks. Lihat juga Border dengan sudut membulat yang memakai ekspresi FX untuk menghasilkan string draw berdasarkan informasi lebar dan tinggi gambar. Anda dapat menghitung posisi gambar memakai rumus FX atau bahkan menentukan posisi memakai ukuran dan lokasi gambar lain (lihat Posisi yang dihitung secara bertahap). Anda juga dapat memakai escape FX di dalam persen escape pada nama file untuk menghasilkan file baru berdasarkan nilai yang dihitung. Untuk contohnya, lihat contoh terakhir di Crop tile.
Semua yang di atas pada dasarnya menjalankan "-format", dan karenanya juga ekspresi FX yang ada di dalamnya, sekali untuk setiap gambar dalam rangkaian gambar saat ini. Operator "-print" bekerja mirip "-identify", hanya saja ia dijalankan sekali saja, dengan akses ke SEMUA gambar dalam rangkaian gambar saat ini. Dengan operator ini Anda dapat memakai 'u[{i}]' untuk mengakses nilai dari gambar mana pun, tidak seperti yang di atas.
Ekspresi Fx dapat diterapkan pada gambar dalam ruang warna lain, jadi saya misalnya dapat mencari tahu nilai 'Hue' (pada kanal 'merah') untuk tiga warna yang berbeda. |

  magick xc:red xc:green xc:blue -colorspace HSL \
          -format '%[fx: s.r ]\n' info:

[IM Output]
Anda juga dapat memakai IM untuk beberapa perhitungan warna langsung, misalnya mencari tahu warna rata-rata dari 'gold', 'yellow', dan 'khaki'. |

  magick xc: -format '%[pixel:(gold+yellow+khaki)/3]' info:

[IM Output]
Sementara yang berikut menunjukkan tampilan warna itu dibandingkan ketiga warna sumbernya... |

  magick xc:gold xc:yellow xc:khaki +append \
          \( xc: -fx '(gold+yellow+khaki)/3' \) \
          -scale 90x30\! -append fx_hues.png

[IM Output]
Anda juga dapat memakai "-print" untuk mencetak informasi. Ini diterapkan sekali saja terhadap seluruh rangkaian gambar. Artinya, operator ini dapat Anda pakai untuk menghitung ekspresi '%[fx:...]' yang jauh lebih rumit yang melibatkan banyak gambar.

Mengakses data dari gambar lain

Namun ada satu masalah serius dalam memakai ekspresi escape FX. IM tidak punya akses langsung ke gambar lain dalam rangkaian gambar saat ini ketika Anda sedang membuat gambar. Umumnya ini memang tidak diperlukan pada pembuatan gambar yang biasa, karena gambar baru umumnya tidak bergantung pada gambar yang sudah ada di memori. Pada dasarnya, bila Anda ingin mengambil warna piksel tertentu dari gambar yang berbeda dengan gambar yang sedang Anda gambari (seperti di atas), atau sedang membuat gambar baru, fungsi inti IM tidak punya kaitan langsung dengan informasi yang diinginkan. Sebagai contoh, bila Anda mencoba membuat label berisi warna piksel 12,26 gambar bawaan "rose:" (sebuah piksel kebiruan), pendekatan langsung akan gagal! |

  magick rose: label:'%[pixel:p{12,26}]' -delete 0 label_fx_direct.gif

[IM Output]
Nah, gambar rose sebenarnya tidak mengandung piksel hitam sama sekali, jadi hasil di atas salah. Cara memperbaikinya adalah mengekstrak informasi yang diinginkan lalu menyimpannya ke dalam metadata global IM. Metadata itu diteruskan ke semua subrutin di dalam inti pustaka, termasuk subrutin untuk pembuatan gambar. |

  magick rose: -set option:mylabel '%[pixel:u.p{12,26}]' -delete 0 \
          label:'%[mylabel]'    label_fx_indirect.gif

[IM Output]
Ini tidak intuitif, tetapi kini kita mendapat hasil yang benar. Tag khusus 'option:' memberi tahu opsi "-set" bahwa Anda ingin pengaturan yang diberikan disimpan sebagai Artifact global, bukan sebagai string 'Attribute' atau 'Properties' gambar, sebagaimana yang juga bisa dilakukan "-define". Namun bentuk "-set" memungkinkan Anda memperluas persen escape saat menyetel Artifact, sedangkan "-define" tidak. Ketika operator "label:" memperluas persen escape-nya, 'key' yang diberikan dicari lebih dulu sebagai 'attribute' atau 'properties' per gambar; bila tidak ketemu, barulah 'key' itu dicari di pengaturan Artifact global. Jadi 'artifact' global yang kita buat dari gambar sebelumnya tetap dipakai, walaupun gambar itu sudah tidak ada lagi saat Artifact itu dibuat. Pada dasarnya pengaturan 'Artifact' bersifat global selama masa hidup perintah "magick", sehingga dapat dipakai untuk meneruskan informasi dari satu gambar ke gambar lain. Untuk API yang diprogram, situasi ini dapat dihindari karena Anda dapat membaca data yang diperlukan langsung dari gambar lalu membuat sendiri string label-nya, tanpa perlu IM menyimpan informasi itu dengan cara yang berbelit-belit seperti ini.


Evaluate dan Function, pengubah kanal bebas

Karena operator FX adalah penangan ekspresi yang ditafsirkan, operator "-evaluate" ditambahkan agar modifikasi gambar yang sederhana dapat dilakukan lebih cepat. Belakangan operator "-function" yang lebih rumit ditambahkan pada IM v6.4.8-8, untuk memberi keleluasaan lebih besar pada penyetelan gambar yang rumit. Kedua operator ini, bersama operator penyesuaian level gambar lain seperti "-negate", "-level", mungkin paling berguna untuk penyetelan kecil pada gambar grayscale, sebelum gambar itu Anda terapkan. Terutama pada gambar grayscale seperti yang dipakai untuk penghapusan latar belakang, overlay highlight dan bayangan, serta pembuatan dan penyetelan halus peta gambar.

Evaluate, operasi matematika sederhana

Operator "-evaluate" pada dasarnya adalah versi cepat tetapi sangat sederhana dari operator "-fx" (sebenarnya ia sudah ada beberapa bulan sebelum FX ditambahkan ke IM). Namun ia terbatas pada satu operasi sederhana saja, memakai satu bilangan konstanta yang diberikan pengguna. Anda dapat mengetahui fungsi apa saja yang sudah tertanam di evaluate memakai

  magick -list evaluate

Ini mencakup fungsi matematika yang lazim, yaitu 'add', 'subtract', 'multiply', dan 'divide', terhadap nilai konstanta. Tidak seperti operator -fx, nilainya tidak dinormalkan ke rentang 0 sampai 1, melainkan tetap berupa nilai warna gambar yang sebenarnya. Karena itu mengurangkan nilai 50 pada IM Q8 (lihat Kualitas dan kedalaman) akan menghasilkan pengurangan yang besar, sedangkan pada IM versi Q16 perubahannya kecil dan nyaris tak terlihat. Namun bila Anda menambahkan '%' pada argumennya, argumen itu akan mewakili persentase dari nilai warna maksimum (dikenal sebagai 'QuantumRange', yang setara dengan '2 _quality_ -1'). Artinya, argumen "-evaluate" dapat Anda buat tidak bergantung pada tingkat kualitas IM, dengan memakai persentase secara tepat pada metode evaluate yang sesuai. Sebagai contoh, mengganti semua nilai warna dalam sebuah gambar menjadi tingkat abu-abu 50% sangat sederhana dan sangat cepat, memakai 'Set ' |

  magick rose: -evaluate set 50%  rose_set_gray.gif

[IM Output]
Operator "-evaluate" juga mencakup fungsi matematika yang lazim, yaitu 'add', 'subtract', 'multiply', dan 'divide'. Sebagai contoh, untuk mengurangi kontras gambar menjadi separuhnya, Anda dapat mem-'divide ' gambar itu dengan '2' lalu mem-'add ' '25% untuk memusatkannya kembali di sekitar abu-abu yang sempurna. |

  magick rose: -evaluate divide 2 -evaluate add 25%  rose_de-constrast.gif

[IM Output]
Cara ini beberapa orde besaran lebih cepat daripada memakai operator "-fx" langsung dengan 'u/2+.25'. Karena itu sebaiknya operator ini Anda pakai lebih dulu daripada "-fx" bila memungkinkan. Masalah besar pada "-evaluate" adalah semua hasilnya dipotong ke batas 0 sampai 'QuantumRange' (kecuali Anda memakai versi HDRI ImageMagick), karena setiap nilai yang diubah disimpan kembali ke data gambar. Artinya, setelah setiap operasi "-evaluate" tersendiri, nilainya bisa terpotong oleh 'QuantumRange'. Karena itu, bila Anda mencoba menerapkan fungsi peningkatan kontras (setara dengan "-fx '2*u-.25' ") apa adanya, hasilnya tidak akan benar, karena nilai yang sudah dikalikan dua akan terpotong sebelum pengurangannya dilakukan. |

  magick rose: -evaluate multiply 2  -evaluate subtract 25% \
          rose_contrast.gif

[IM Output]
Pertama 'multiply ' akan memotong semua nilai warna yang besar ke nilai maksimum, lalu 'subtract' akan memotong nilai batas bawahnya. Hasilnya adalah pemotongan batas atas yang keliru, sehingga menghasilkan gambar yang gelap dan warnanya menyimpang. Solusi langsungnya adalah mem-'subtract ' konstanta yang sesuai lebih dulu (melakukan pemotongan batas bawah yang final tetapi benar), sebelum mengalikan, yang efektifnya memakai rumus setara '(u-.125)*2' |

  magick rose: -evaluate subtract 12.5%  -evaluate multiply 2 \
          rose_contrast2.gif

[IM Output]
Namun ada banyak alternatif untuk masalah 'pemotongan' ini. Yang pertama dan paling logis adalah metode fungsi Polynomial yang lebih baru (lihat di bawah). Alternatif lain termasuk memakai operator penyesuaian level atau bahkan penyesuaian level menurut warna, untuk sekadar menyebutkan nilai warna asli yang ingin Anda regangkan hingga memenuhi seluruh rentang warna. Pada dasarnya, berhati-hatilah terhadap pemotongan nilai warna ketika memakai beberapa metode "-evaluate" sekaligus.
Operator "-evaluate", seperti "-fx" (dan sebagian besar operator IM tingkat rendah lain), terpengaruh oleh "-channel". Ini memungkinkan Anda mengendalikan transparansi alpha sebuah gambar terpisah dari kanal warnanya. Dan benar, seperti "-fx", transparansi diperlakukan sebagai 'nilai alpha' dan bukan nilai 'matte'. Sebagai contoh, untuk membuat sebuah gambar transparan 50%, sebagai bagian dari operasi bertipe Dissolve. |

  magick rose: -alpha set  -channel A -evaluate divide 2   rose_transparent.png

[IM Output]
Hasilnya adalah gambar semitransparan, yang berarti ketika ditampilkan, separuh warna yang Anda lihat adalah warna latar belakang halaman web. Jadi gambar yang tampil menjadi redup ke arah warna latar belakang. Saya juga sering mendapati bahwa memakai "-evaluate" pada masing-masing kanal warna lebih mudah dilakukan sebelum memisahkan berbagai kanal itu menjadi gambar terpisah untuk keperluan tertentu (lihat Memisahkan kanal). Sebagai contoh, di sini saya memakainya untuk melakukan grayscaling dengan cara yang cepat tetapi tidak biasa. Pada dasarnya saya mengalikan setiap kanal dengan takaran yang sesuai, lalu memisahkan dan menjumlahkan kanal-kanal itu sehingga menghasilkan gambar yang di-grayscale memakai perbandingan warna tertentu. |

  magick test.png -channel R -evaluate multiply .2 \
                   -channel G -evaluate multiply .5 \
                   -channel B -evaluate multiply .3 \
                   -channel RGB -separate -background black -compose plus -flatten gray_253.png

[IM Output]

Evaluate, fungsi matematika

Di dalam Evaluate juga ada sekumpulan fungsi matematika bertujuan khusus. Fungsi-fungsi ini umumnya diimplementasikan memakai nilai warna yang dinormalkan (rentang 0 sampai 1), dengan keluaran yang dinormalkan kembali agar pas dengan seluruh rentang warna gambar. Fungsi kontras sigmoidal juga contoh penyesuaian fungsi matematis semacam ini.

Pangkat

Fungsi 'Pow ' (ditambahkan pada IM v6.4.1-9) misalnya bekerja dengan nilai warna yang dinormalkan, dan memungkinkan pengguna mengubah kecerlangan gambar. Fungsi ini persis setara dengan fungsi pow() pada C, (memakai nilai warna yang dinormalkan dalam rentang 0 - 1)

    value = pow(value, constant)

Karena itu, untuk membuat gradien 'parabolik' Anda dapat memakai argumen '2'. Atau memakai nilai '0.5' untuk membuat gradien 'akar kuadrat'. Sebagai contoh...

  magick -size 20x600  gradient: -rotate 90  gradient.png
  magick gradient.png  -evaluate Pow  2   eval_pow_parabola.png
  magick gradient.png  -evaluate Pow 0.5  eval_pow_sq_root.png

[IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]

| Ketiga gambar di bawah menunjukkan profil gradien yang dihasilkan, baik sebagai grafik maupun sebagai gambarnya sendiri. Ini memudahkan kita melihat bagaimana satu gambar gradien dimodifikasi menjadi gradien yang lain. Gambar itu dibuat memakai program penggambar grafikGnuplot, lewat skrip "im_profile" di direktori Scripts IM Examples.
Ini sebenarnya setara dengan operator penyesuaian gamma tetapi dengan argumen yang dibalik. Sebagai contoh, operasi "-gamma 2" akan setara dengan "-evaluate pow 0.5" atau fungsi operasi 'akar kuadrat'. Begitu pula "-gamma 0.5" setara dengan pengkuadratan memakai "-evaluate pow 2"Dengan melakukan beberapa manipulasi gradien khusus, Anda dapat memakai metode ini untuk mengubah gradien linear menjadi busur lingkaran yang rumit. |

  magick -size 20x300  gradient: -rotate 90 \
          -evaluate Pow 2 -negate -evaluate Pow 0.5 \
          -flop \( +clone -flop \) +append  eval_circle_arc.png

[IM Output] [IM Output]
Bagi yang ingin mengurainya, baris kedua pada perintah di atas setara dengan ekspresi FX 'sqrt(1-u^2)'. Ini menghasilkan busur seperempat lingkaran tunggal, yang lalu di-flop dan disambung sehingga menghasilkan busur setengah lingkaran. Cara ini juga jauh lebih cepat daripada memakai ekspresi FX, meskipun memerlukan lebih banyak langkah tersendiri (yang lebih kecil). Lihat juga Fungsi Polynomial yang lebih canggih.

Logaritmik

Fungsi 'Log ' (ditambahkan pada IM v6.4.2-1) juga bekerja dengan nilai yang dinormalkan (dengan tambahan 1.0 untuk menghindari ketakhinggaan), dengan konstanta yang diberikan dipakai sebagai basis logaritma. Rumus sebenarnya (dengan nilai yang dinormalkan) adalah...

    value = log(value*constant+1.0)/log(constant+1.0)

Sebagai contoh... |

  magick gradient.png -evaluate Log 10  eval_log.png

[IM Output] [IM Output]
Ini mungkin tampak sangat mirip metode evaluate Pow sebelumnya, tetapi tidak persis sama. 'Log' menghasilkan lereng yang cukup jelas ketika mendekati '0', sedangkan 'Pow' menghasilkan lereng yang tegak. Nilainya mengendalikan lereng itu. Fungsi logaritmik juga berkaitan erat dengan fungsi eksponensial, yang saat ini hanya diimplementasikan sebagai operator penyesuaian kontras sigmoidal. Operator itu punya ciri lereng yang sama seperti yang terlihat pada kurva logaritmik di atas. Ini menjelaskan mengapa "-sigmoidal-contrast" adalah teknik yang lebih baik untuk memperbaiki gambar dalam kondisi cahaya rendah daripada penyesuaian gamma atau kurva 'pangkat'.

Sinus dan kosinus

Sejak IM v6.4.8-8 metode 'sin ' dan 'cos ' ditambahkan. Metode ini mengambil nilai yang ada pada gambar lalu menormalkannya menjadi sebuah sudut sehingga seluruh rentangnya mencakup satu lingkaran penuh. Hasilnya diberi bias 50% dan diskalakan agar kembali pas dengan rentang nilai yang normal. Konstantanya dipakai sebagai pengali bagi nilai (dan karenanya bagi sudut) sehingga 'N' berarti fungsi itu akan mengelilingi lingkaran 'N' kali sepanjang seluruh rentang nilai. Rincinya, fungsi ini didefinisikan (memakai nilai yang dinormalkan) sebagai...

   value = 0.5 * sin( constant*value*2*PI ) + 0.5
   value = 0.5 * cos( constant*value*2*PI ) + 0.5

Pada intinya, yang dilakukan fungsi-fungsi ini adalah memetakan ulang nilai gambar (biasanya nilai grayscale) ke dalam kurva sinus/kosinus. Sebagai contoh, di sini saya mengambil sebuah gambar gradien lalu memodifikasinya memakai metode evaluate ini.

  magick gradient.png  -evaluate sin 1  eval_sin_1.png
  magick gradient.png  -evaluate cos 1  eval_cos_1.png

[IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]

Nah, karena parameter konstantanya adalah pengali sudut, nilai yang diberikan ke metode evaluate akan menghasilkan sebanyak itu puncak sepanjang seluruh gradien di dalam sebuah gambar. |

  magick gradient.png -evaluate cos 5  -negate  eval_cos_5.png

[IM Output] [IM Output]
Ini sempurna untuk banyak keperluan, dari menghasilkan efek riak atau dispersi sampai menghasilkan kurva perpindahan yang tampak beriak. Dengan memakai konstanta pengali '0.5' Anda dapat dengan mudah mengubah gradien linear menjadi gradien kurva sinus, yang lerengnya tetap sama dengan aslinya. Dengan menegasikan hasilnya, Anda dapat memastikan gradien itu melereng dengan benar. |

  magick gradient.png -evaluate cos 0.5  -negate  eval_cos.5.png

[IM Output] [IM Output]
Ini bagus sekali untuk menghasilkan gradien mulus yang dipakai pada foto yang saling menumpuk. Namun kedua metode "-evaluate" terakhir ini jarang dipakai karena sudah digantikan Fungsi Sinusoid (lihat di bawah) yang lebih umum dan memberi lebih banyak opsi kendali, melampaui sekadar opsi frekuensi.


Function, evaluate multi-argumen

Pembangkit gelombang di atas terbukti sangat berguna, terutama dengan pemetaan gambar distorsi. Tetapi ternyata diperlukan kendali fungsi yang jauh lebih halus, yang menuntut lebih dari satu parameter. Karena itu operator "-function" ditambahkan pada IM v6.4.8-9. Pada dasarnya "-function" adalah bentuk multi-argumen dari "-evaluate". Namun tidak seperti operator Evaluate, operator ini, seperti operator matematis, semua fungsi di atas hanya bekerja pada nilai kanal gambar yang dinormalkan (rentang 0.0 sampai 1.0), yang dalam banyak kasus membuatnya lebih mudah dipakai.

Fungsi Polynomial

Metode 'polynomial ' menerima nilai sebanyak apa pun, dan akan memodifikasi nilai warna dalam sebuah gambar menurut ekspresi yang diberikan, jauh lebih cepat daripada yang bisa dilakukan operator FX.

-function   Polynomial   a,b,c,...

Setiap nilai akan dipakai sebagai koefisien dari orde tertinggi ke terendah, sehingga menghasilkan polinomial dengan sebanyak itu suku. Sebagai contoh, argumen '4,-4,1' akan menghasilkan ekspresi polinomial yang setara dengan ekspresi "-fx" " 4*u^2 - 4*u + 1 ". Bila Anda ingat matematika SMA, tentu Anda tahu bahwa fungsi polinomial ini menghasilkan kurva parabola yang bergerak dari 1.0 ke 0.0 lalu kembali ke 1.0, sepanjang rentang warna masukan ('u') 0.0 sampai 1.0. Artinya, warna hitam dan putih akan dijadikan 'putih', dan abu-abu sempurna dijadikan 'hitam'. |

  magick gradient.png -function Polynomial 4,-4,1  func_parabola.png

[IM Output] [IM Output]
Anda bahkan dapat membuat gradien yang jauh lebih rumit, misalnya polinomial kuartik, yang merupakan hasil pembuatan penyesuaian kurva level memakai sekumpulan 'titik kendali level'. Cara ini biasanya dipakai untuk menyetel warna sebuah gambar agar mendapat berbagai efek shading. |

  magick gradient.png -function Polynomial '-25, 53, -36, 8.3, 0.2' \
          func_quartic.png

[IM Output] [IM Output]
Tentu saja modifikasi linear sederhana juga bisa, persis seperti yang Anda dapat bila memakai operator Level... |

  magick gradient.png -function Polynomial '4, -1.5' func_linear.png

[IM Output] [IM Output]
Namun perhatikan bahwa 'Polynomial' tidak dapat Anda pakai untuk melakukan operasi threshold penuh, karena itu menuntut koefisien tak hingga, meski Anda bisa mendekatinya. Nilai tunggal wajarnya hanya menjadi sebuah konstanta, dan menghasilkan penetapan langsung nilai itu. Dengan kata lain, ia sama seperti metode "-evaluate Set ", dalam hal ini ke nilai abu-abu 33%. |

  magick gradient.png -function Polynomial 0.33 func_constant.png

[IM Output] [IM Output]
Dengan memadukan 'Polynomial' dengan fungsi matematika lain, Anda dapat membuat modifikasi gradien yang lebih rumit lagi. Misalnya dengan mengambil akar kuadrat sebuah polinomial, saya dapat membuat busur lingkaran sejati di atas gradien linear. Ekspresi "-fx" yang setara adalah 'sqrt( -4*u^2 + 4*u + 0 )'... |

  magick gradient.png -function Polynomial -4,4,0 -evaluate Pow 0.5 \
          func_circle_arc.png

[IM Output] [IM Output]
Lihat juga metode evaluate Pow sebagai alternatif dari yang di atas.

Fungsi Sinusoid

Metode fungsi 'Sinusoid ' adalah versi yang jauh lebih canggih dari metode "-evaluate" 'sin' dan 'cos', dan sebenarnya dapat menirukan kedua fungsi itu, hanya saja Anda punya kendali yang jauh lebih baik atas cara ia memodifikasi nilai warna dalam sebuah gambar.

-function   Sinusoid   frequency,phase,amplitude,bias

Dan diimplementasikan dengan rumus...

  value = ampl * sin(2*PI( freq*value + phase/360 ) ) + bias

Ini mungkin tampak rumit, tetapi justru memastikan fungsi ini mudah dipakai. Hanya nilai pertama, 'frequency', yang bekerja persis seperti di atas, yang wajib; semua parameter lain bersifat opsional. Secara bawaan ia akan menghasilkan kurva sinus. |

  magick gradient.png -function Sinusoid 1    func_sine.png

[IM Output] [IM Output]
Dengan menambahkan argumen 'phase ' dalam derajat, Anda dapat menentukan sudut awal kurva itu. Sehingga Anda dapat mengubah kurva sinus bawaan menjadi kosinus. |

  magick gradient.png -function Sinusoid 1,90   func_cosine.png

[IM Output] [IM Output]
Dengan menyetel 'frequency' dan 'phase', saya dapat langsung mengubah gradien linear menjadi gradien sinusoidal yang mulus dari hitam ke putih (minimum ke maksimum sepanjang kurva sinus). Lihat metode evaluate Cosine untuk cara yang tidak langsung. |

  magick gradient.png -function Sinusoid 0.5,-90 func_sine_grad.png

[IM Output] [IM Output]
Dua nilai opsional berikutnya, 'amplitude' dan 'bias', mengendalikan skala dan garis tengah kurva sinusoidal. Sebagai contoh, di sini saya membuat gelombang (kurva kosinus yang dinegasikan) yang berayun antara putih dan abu-abu (nilai berkisar dari 0.75 ±0.25, atau 0.5 sampai 1.0), dimulai dan diakhiri pada putih. |

  magick gradient.png -function Sinusoid 5,90,.25,.75  func_sine_bias.png

[IM Output] [IM Output]
Hati-hati dengan parameter terakhir ini karena keduanya mudah membuat bentuk gelombangnya melampaui batas rentang nilai warna, sehingga terpotong (kecuali Anda memakai versi HDRI ImageMagick).

Fungsi Arcsin

Fungsi sinusoid invers 'Arcsin ' ditambahkan pada IM v6.5.3-0. Ini kurva khusus yang diperlukan untuk menghasilkan Cylindrical Displacement Map. Parameternya adalah...

-function   Arcsin   width,center,range,bias

Dan diimplementasikan dengan rumus...

  value = range/PI * asin(2/width*( value - center ) ) + bias

Nilai bawaan (bila tidak didefinisikan) '1, 0.5, 1, 0.5' memastikan fungsi ini terpusat sehingga mencakup seluruh rentang warna dari 0,0 sampai 1,1. |

  magick gradient.png -function Arcsin 1    func_arcsin.png

[IM Output] [IM Output]
Dengan membagi dua nilai 'width ', kurva yang dihasilkan menjadi... |

  magick gradient.png -function Arcsin 0.5    func_arcsin_width.png

[IM Output] [IM Output]
'center ' memungkinkan kurva diposisikan ulang menurut nilai abu-abu masukan. |

  magick gradient.png -function Arcsin 0.4,0.7 func_arcsin_center.png

[IM Output] [IM Output]
Argumen 'range ' berfungsi mengurangi rentang keluaran nilai warna, dan 'bias ' akan menggeser titik tengah rentang itu. |

  magick gradient.png -function Arcsin 0.5,0.5,0.5,0.5  func_arcsin_range.png

[IM Output] [IM Output]
Perhatikan bagaimana nilai yang menjadi tidak valid akibat fungsi ini ditangani. Ini memberi kendali yang lebih baik ketika fungsi dipakai pada displacement, sekaligus menyediakan cara untuk membersihkannya. Nilai yang sebenarnya dipakai adalah '_bias_ ± _range_ /2', seperti yang Anda duga. Perhatikan pula, jika 'width ' atau 'range ' dibuat negatif, kemiringan fungsinya akan terbalik akibat nilai negatif itu. |

  magick gradient.png -function Arcsin -1    func_arcsin_neg.png

[IM Output] [IM Output]

Fungsi Arctan

Metode 'Arctan ' ditambahkan pada IM v6.5.3-1. Parameternya adalah...

-function   Arctan   slope,center,range,bias

Dan diimplementasikan dengan rumus...

  value = range/PI * atan(slope*PI*( value - center ) ) + bias

Seperti terlihat, fungsi ini hampir persis sama dengan fungsi 'Arcsin', hanya dengan sedikit perubahan agar lebih berguna. Bahkan kumpulan nilai bawaannya pun sama (bila tidak didefinisikan) '1, 0.5, 1.0, 0.5'. Artinya, kalau nilai slope '1.0' yang ditentukan, kemiringan perubahan histogramnya menghasilkan perubahan 1:1 di sekitar abu-abu murni (tanpa penskalaan), sementara putih dan hitam menjadi lebih abu-abu. Sebagai contoh |

  magick gradient.png -function Arctan 1 func_arctan.png

[IM Output] [IM Output]
Artinya, bagian tengah gradien sebenarnya dibiarkan apa adanya, hanya ujung hitam dan putihnya yang berkurang kontrasnya. Makin besar 'slope ' kurvanya, makin kuat pula gradien di bagian tengah (makin termampatkan di tengah), sebesar nilai itu. |

  magick gradient.png -function Arctan 10 func_arctan_10.png

[IM Output] [IM Output]
Dalam banyak hal ini sangat mirip dengan operator modifikasi warna kontras sigmoidal. Namun fungsi 'Arctan' TIDAK PERNAH benar-benar mencapai batas rentang keluaran berupa hitam dan putih murni. Ia mendekati batas itu tetapi tidak pernah melewatinya. Seperti pada fungsi-fungsi sebelumnya (dan kontras sigmoidal), argumen kedua menyesuaikan posisi kurva relatif terhadap nilai gradien masukan. |

  magick gradient.png -function Arctan 10,.7 func_arctan_center.png

[IM Output] [IM Output]
Dan dua argumen terakhir, 'range ', dipakai untuk menyesuaikan rentang keluaran nilai yang akan dihasilkan. Misalnya, dengan sedikit melebarkan nilai ini, seluruh rentang nilai yang mungkin dapat dipastikan tercakup. |

  magick gradient.png -function Arctan 5,0.7,1.2 func_arctan_range.png

[IM Output] [IM Output]
Namun kalau yang benar-benar Anda inginkan adalah membuat kurva untuk mengubah keseluruhan kontras sebuah gambar dengan cara ini, lebih lazim memakai operator kontras sigmoidal yang memang dirancang untuk keperluan itu. Penggunaan fungsi gradien 'Arctan' yang lebih lazim adalah membuat kurva yang dengan sangat cepat mendekati suatu nilai tertentu tanpa melampauinya. Nilai-nilai pembatas inilah yang dikendalikan argumen 'range ' dan 'bias '. Sebagai contoh, kurva berikut mengubah gradien di sebuah gambar sehingga menghasilkan threshold yang sangat tajam di sekitar tingkat abu-abu masukan 0.7, tetapi dengan nilai yang berubah di antara batas rentang 0.5 dan 1.0 |

  magick gradient.png -function Arctan 15,0.7,0.5,0.75 func_arctan_typ.png

[IM Output] [IM Output]
Ini sesuatu yang tidak bisa dihasilkan kontras sigmoidal.


Matematika pada gambar gradien

Fungsi-fungsi di atas menyediakan transformasi yang sangat mendasar untuk gambar gradien. Tetapi bagaimana kalau kita ingin berhitung dengan dua gambar gradien atau lebih? Yaitu memodifikasi satu gradien memakai gradien gambar lain. Untuk itu kita perlu memakai metode compose matematis khusus (seperti "Plus" dan "Divide"). Namun sebelum mulai, saya ingin memberi satu peringatan. Kalau gambar gradien Anda murni grayscale tanpa kanal alpha, metode compose matematis bisa dipakai langsung. Namun kalau metode itu hendak dibatasi pada kanal tertentu, atau diterapkan pada kanal alpha (transparansi), pastikan pengaturan "-channel" yang sesuai sudah disetel, tanpa flag kanal 'Sync' khusus. Lihat Matematika kanal gambar memakai komposisi gambar untuk detailnya. Biasanya memakai metode compose matematis tidak terlalu sulit. Kerumitan muncul ketika gradien yang dipegang juga mengandung 'bias'. Yaitu, gradien itu mewakili nilai 'nol' pada abu-abu 50%, dan mencakup rentang dari -1 (hitam) sampai +1 (putih). Gambar semacam ini sering dipakai untuk pemetaan gambar distorsi. Karena itu, berhitung dengan 'gradien berbias ' adalah masalah yang sesungguhnya, dan itulah yang akan dibahas lebih khusus di sini.

Melemahkan gradien berbias

Sebagai contoh, di sini saya ingin membuat gelombang sinus, tetapi yang amplitudonya kecil di awal lalu membesar. Ini dikenal sebagai 'pelemahan' sebuah gradien berbias. Atau dengan kata lain, mengalikan gradien berbias dengan gradien absolut lain. Begitu pula cara kerja 'Modulasi Amplitudo ' seperti pada radio AM! Jadi pertama-tama kita perlu gelombang sinus, yang bisa kita hasilkan begitu saja dari gradien linear...

  magick -size 5x300 gradient: -rotate 90   math_linear.png
  magick math_linear.png  -evaluate sine 12  math_sine.png

[IM Output] [IM Output]

Sekarang, untuk melemahkannya kita mengalikan gelombang sinus itu dengan gradien linear, memakai komposisi alpha Multiply...

  magick math_sine.png  math_linear.png  \
          -compose Multiply -composite  math_sine_2.png

[IM Output] [IM Output] [IM Output]

Tetapi untuk memakainya, katakanlah pada Water Ripples, Displacement Map, gelombangnya harus tetap terpusat di abu-abu sempurna. Untuk itu kita perlu menambahkan bias ke gambar aslinya. Kebetulan ini fungsi yang sama dengan yang kita pakai untuk mengalikan gambar asli, dinegasikan lalu dibagi dua....

  magick math_linear.png -negate -evaluate divide 2  math_bias.png
  magick math_sine_2.png  math_bias.png \
          -compose Plus -composite  math_attenuated.png

[IM Output] [IM Output] [IM Output]

Dengan begitu kita punya gradien gelombang sinus yang dilemahkan secara linear, cocok dipakai sebagai displacement map.

Tentu saja seluruh proses itu bisa dikerjakan dalam satu perintah, dan pelemahannya pun tidak harus linear sederhana. Sebagai contoh, di sini saya melemahkan gelombang sinus berfrekuensi tinggi memakai gelombang kosinus yang dinegasikan, alih-alih gradien linear.

  magick math_linear.png  -evaluate cos 1 -negate  math_cosine_peak.png
  magick math_sine.png  math_cosine_peak.png \
          \( -clone 0,1 -compose multiply -composite \) \
          \( -clone  1  +level 50%,0 \
             -clone  2  -compose plus -composite \) \
          -delete 0--2  math_cosine_atten.png

[IM Output] melemahkan [IM Output] [IM Output]

Sejak IM v6.5.4-3, semua langkah di atas kini bisa dikerjakan dalam satu metode compose saja, memakai metode compose Mathematics khusus. Pada dasarnya dengan mengenali bahwa operasi pelemahan adalah rumus Sc*Dc-.5*Sc+.5, atau argumen "1,-.5,0,.5". |

  magick math_sine.png  math_cosine_peak.png \
          -compose Mathematics -set option:compose:args 1,-.5,0,.5 \
          -composite  math_attenuate.png

[IM Output]
Hasil yang sama juga bisa dicapai dengan lebih dulu menyesuaikan gradien pelemahnya memakai Fungsi Polynomial, lalu memakai operator compose Exclusion untuk menggabungkan gambarnya. |

  magick math_sine.png \( math_cosine_peak.png -function polynomial -.5,.5 \) \
          -compose Exclusion -composite  math_poly_excl.png

[IM Output]

Mengalikan gradien berbias

Tetapi bagaimana kalau KEDUA fungsinya berbias, sehingga abu-abu sempurna berarti nol, dan hitam serta putih mewakili rentang dari -1 sampai +1? Nah, ini sedikit lebih rumit karena keduanya tidak bisa begitu saja dikalikan dan diharapkan hasilnya benar, sebab perkaliannya bisa melibatkan nilai negatif. Perlu kehati-hatian agar nilainya tidak berakhir ter-clipping dan negasi kurvanya tetap benar di gambar hasil. Kiatnya adalah memecah perkalian itu menjadi beberapa langkah. Yaitu, A × B dapat pula ditulis sebagai A × abs(B) × sign(B). Dengan begitu perkalian dengan nilai negatif dapat dihindari, karena nilai negatif tidak bisa disimpan di gambar gradien biasa. Jadi yang perlu kita lakukan hanyalah mengambil salah satu gradien bias dan memisahkannya menjadi dua bagian agar keduanya dapat diterapkan ke gradien yang lain dengan tepat. 'sign()' dari gradien berbias, atau mask bagian mana yang negatif, bisa diekstrak dengan menerapkan threshold pada gradien di tingkat biasnya. Nanti gradien yang lain dapat dinegasikan secara selektif memakai Composite Difference bersama gambar threshold itu. 'abs()' dari gradien berbias mudah diekstrak memakai Solarize, lalu dinegasikan dan dilipatduakan (memakai Level) untuk mendapatkan nilai absolut gradien dalam rentang 0.0 sampai 1.0. Karena offset biasnya juga kita perlukan sebagai bagian dari perkalian (seperti pada Melemahkan gradien berbias di atas), keluaran solarize yang sudah dinegasikan dan diskalakan separuh itu bisa langsung dipakai, sebelum diubah menjadi nilai absolut gradien. Jadi mari kita ubah satu gradien menjadi tiga komponen ini.

  magick math_cosine_peak.png  -threshold 50% -negate  math_m_sign.png
  magick math_cosine_peak.png     -solarize 50%        math_m_bias.png
  magick math_m_bias.png          -level 50%,0         math_m_abs.png

| [IM Output] | Tanda gradien
putih = negatif
[IM Output] | [IM Output] | Offset bias
| [IM Output] | Nilai absolut

Setelah ketiga bagian dari salah satu gambar gradien itu kita punya, semuanya bisa digabungkan dengan gradien yang lain. Caranya, kalikan dengan nilai absolutnya, tambahkan kembali biasnya, lalu negasikan bagian yang semestinya menjadi negatif.

  magick math_sine.png   math_m_abs.png \
          -compose Multiply -composite    math_m_1.png
  magick math_m_1.png   math_m_bias.png \
          -compose Plus -composite        math_m_2.png
  magick math_m_2.png   math_m_sign.png \
          -compose Difference -composite  math_multiply.png

[IM Output] [IM Output] [IM Output]
[IM Output] [IM Output]
tanda [IM Output] [IM Output]

Dan itulah perkalian sempurna dari dua gambar gradien bias! Berikut sekali lagi, tetapi seluruhnya dalam satu perintah...

  magick math_sine.png  math_cosine_peak.png \
          \( -clone  1  -threshold 50% -negate \) \
          \( -clone  1      -solarize 50%      \) \
          \( -clone  3      -level 50%,0       \) \
          \( -clone 0,4 -compose multiply   -composite \
             -clone  3  -compose plus       -composite \
             -clone  2  -compose difference -composite \) \
          -delete 0--2    math_multiply_2.png

[IM Output] [IM Output] [IM Output]

Satu catatan terakhir: tidak seperti pelemahan, perkalian gradien berbias ini bersifat komutatif. Artinya, menukar gambar masukannya tidak mengubah hasil akhir. Karena yang di atas setara dengan rumus 2*Sc*Dc-Sc-Dc+1, sejak IM v6.5.4-3 langkah-langkah rumit di atas dapat dikerjakan sebagai satu metode compose 'Mathematics' saja dengan argumen "2,-1,-1,1". |

  magick math_sine.png  math_cosine_peak.png \
          -compose Mathematics -set option:compose:args 2,-1,-1,1 \
          -composite  math_bias_multiply.png

[IM Output]
Itu jelas metode yang jauh lebih mudah dan cepat daripada belasan langkah atau lebih yang dibutuhkan tanpa metode compose berargumen ini. Kebetulan, begitu saya melihat rumus itu, saya sadar bahwa ini ternyata hanyalah negasi dari metode compose 'Exclusion'. Aneh tapi nyata. Karena itu perintah berikut juga menghasilkan perkalian berbias nol yang sama. |

  magick math_sine.png  math_cosine_peak.png \
          -compose exclusion -composite -negate  math_excl_neg.png

[IM Output]

Menjumlahkan gradien berbias

Dengan hadirnya metode compose 'Mathematics', menjumlahkan gradien berbias pun relatif mudah. Rumus FX yang setara adalah "u+v-0.5", atau argumen compose "0,1,1,-.5". Sebagai contoh, berikut ini contoh transformasi Fourier yang dulu saya hasilkan dengan tangan, yang memerlukan penjumlahan 3 sinusoid berbias dan sebuah nilai DC konstan.

  magick math_linear.png -function sinusoid 3.5,0,.25     wave_1.png
  magick math_linear.png -function sinusoid 1.5,-90,.13   wave_2.png
  magick math_linear.png -function sinusoid 0.6,-90,.07   wave_3.png

  magick wave_1.png wave_2.png wave_3.png -background gray40 \
          -compose Mathematics -set option:compose:args 0,1,1,-.5 \
          -flatten  added_waves.png

[IM Output] [IM Output] [IM Output] [IM Output]

Perhatikan pada contoh di atas bagaimana saya memakai operator "-flatten" dengan pengaturan "-background" untuk melakukan komposisi banyak gambar. Atau dalam hal ini 'Jumlah Berbias' dari semua gambar yang diberikan ditambah konstanta latar belakangnya.

Modulasi frekuensi

Dengan menerapkan sebuah fungsi langsung pada keluaran fungsi lain, hasilnya TIDAK sederhana. Sebabnya, semua fungsi matematika ini diterapkan pada 'nilai' gradien tiap piksel, bukan pada nilai x piksel itu di dalam gradien. Sebagai contoh.... |

  magick gradient.png  -evaluate sin 0.5 -normalize \
                        -evaluate cos  8  math_cos_var.png

[IM Output] [IM Output]
Ini menghasilkan fungsi yang sangat rumit, yang pada dasarnya setara dengan

cos( 8 * sin( _{value}_ /2 ) )

Dengan kata lain, frekuensinya berubah-ubah, mengikuti gradien kurva sinus yang pertama. Pada dasarnya, makin cepat gradien berubah di gambar asli, makin kecil jarak antarpuncaknya. Namun tinggi (amplitudo) puncaknya tidak berubah. Beginilah sebenarnya 'Modulasi Frekuensi ' bekerja: fungsi yang tampak sederhana memberi hasil yang sangat rumit.


Sedang dikerjakan

Aneka teknik transformasi gambar.

Ini belum dicontohkan, tetapi merupakan beberapa transformasi dasar yang
dikembangkan IM dan mungkin berguna.  Kalau Anda punya efek menarik, silakan berkontribusi.

   pikselisasi gambar
      perkecil gambar 10 kali lalu skalakan gambar 10 kali untuk menghasilkan
      blok berisi warna yang kira-kira dirata-ratakan.
      Sebagai contoh...
         magick input.jpg -resize 10% -sample 1000% output.jpg

  Meluruskan gambar yang sedikit terputar

    -deskew {threshold}
       luruskan sebuah gambar. Threshold 40% cocok untuk kebanyakan gambar.

    Gunakan -set option:deskew:auto-crop {width} untuk memangkas gambar secara
    otomatis. Argumen set adalah lebar piksel latar belakang gambar (mis. 40).

    Secara program, kami memangkas otomatis dengan menjalankan filter median
    pada gambar untuk menghilangkan noise salt-n-pepper.  Berikutnya kami ambil
    batas gambar dari hasil filter median itu dengan faktor fuzz (mis. -fuzz 5%).
    Terakhir kami pangkas gambar asli menurut batas itu.  Kodenya seperti ini:

      median_image=MedianFilterImage(image,0.0,exception);
      geometry=GetImageBoundingBox(median_image,exception);
      median_image-DestoryImage(median_image);

      print("  Auto-crop geometry: %lux%lu%+ld%+ld",
                geometry.width,geometry.height, geometry.x,geometry.y);
      crop_image=CropImage(rotate_image,&geometry,exception);

    Lihat [Trim gambar 'noisy'](crop.html#trim_blur)

  Segmentasi
    lihat skrip
       [divide_vert](https://usage.imagemagick.org/scripts/divide_vert)
       [segment_image](https://usage.imagemagick.org/scripts/segment_image)
    untuk beberapa skrip sederhana yang saya tulis guna menyegmentasi gambar
    yang terdefinisi baik menjadi bagian-bagian yang lebih kecil.   Saya berharap
    fungsi segmentasi sederhana seperti ini bisa masuk ke pustaka inti, agar hal
    seperti pembagian otomatis animasi GIF dan pemisahan gambar serta diagram dari dokumen pindaian dapat dilakukan.