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

Contoh penggunaan ImageMagick -- anti-aliasing

Kata pengantar dan indeks contoh penggunaan ImageMagick
Pengantar anti-aliasing
Menggambar hanya dengan warna tertentu
Menggambar lingkaran bitmap tipis
Masalah anti-aliasing dan flood fill

Anti-aliasing adalah bagian utama dari semua operasi penggambaran di dalam ImageMagick. Sayangnya hal itu juga bisa menimbulkan banyak masalah. Halaman ini berusaha membahas masalah-masalah tersebut sekaligus menyajikan solusinya.


Pengantar anti-aliasing ImageMagick, ketika menggambar gambar, melakukannya dengan cara yang sangat khas. Ia menggambarnya lewat operasi yang disebut "anti-aliasing". Untuk memperagakannya, saya akan menggambar sebuah gambar di atas latar belakang transparan, lalu memperbesar sebagian kecil gambar itu supaya terlihat apa yang sebenarnya terjadi.

   magick -size 80x80 xc:none \
            -fill white  -draw "circle 40,40 15,20" \
            -fill black  -draw "line 5,30 78,2"    drawn.png
    magick drawn.png -crop 10x10+50+5 +repage -scale 80x80  drawn_mag.png

[IM Output] [IM Output]

Sekilas tentu terpikir bahwa gambar di atas hanya punya tiga warna, 'white', 'black', dan 'transparent', karena hanya itu yang kita minta untuk dipakai IM. Tetapi seperti terlihat saat gambar itu diperbesar, di dalamnya ada bermacam-macam warna. Dengan cara itu ImageMagick membuat gambar tampak lebih mulus dan lebih enak dipandang, memakai teknik yang disebut 'anti-aliasing'. Ini istilah keren yang artinya piksel tepi objek diisi dengan campuran warna dan bahkan transparansi, supaya objeknya tampak lebih mulus. Kalau anti-aliasing tidak dilakukan, tepi semua objek yang digambar akan punya efek bertangga yang disebut 'aliasing', walau lebih lazim disebut 'jaggies'. Di sini kita menggambar gambar itu lagi, tetapi kali ini kita meminta IM mematikan operasi anti-aliasing otomatisnya, memakai "+antialias".

   magick -size 80x80 xc:none +antialias \
            -fill white  -draw "circle 40,40 15,20" \
            -fill black  -draw "line 5,30 78,2"    drawn_jaggies.png
    magick drawn_jaggies.png -crop 10x10+50+5 +repage -scale 80x80 \
            drawn_jaggies_mag.png

[IM Output] [IM Output]

Kali ini gambarnya benar-benar hanya punya tiga warna. Tetapi hasilnya sama sekali tidak enak dipandang. Pada IM terbaru, garis setebal satu piksel digambar dengan cara bertangga. Pada IM yang lebih lama, garisnya juga akan tampak cukup tebal sehingga kelihatan makin buruk. Pada dasarnya ini bukan sesuatu yang biasanya ingin dilakukan. Efek bertangga dari 'aliasing', yang lazim juga disebut 'jaggies', justru itulah yang berusaha dihindari IM. Tetapi kalau warna tertentu yang Anda inginkan, hal ini harus diterima, atau pakailah teknik lain (seperti kuantisasi warna) untuk memastikan hanya warna tertentu yang terpakai. Perhatikan bahwa sebenarnya ada dua bentuk anti-aliasing yang berlangsung. Yang pertama adalah pembauran warna putih dan hitam di dalam gambar, yang menghasilkan berbagai gradasi warna, dalam hal ini abu-abu. Bentuk yang lain adalah pembauran warna dengan transparansi untuk menghasilkan piksel semitransparan di dalam gambar. Yang belakangan ini perlu diingat, sebab banyak format gambar (seperti GIF) tidak bisa menangani piksel semitransparan dan akan menjadikan piksel semacam itu sepenuhnya buram atau sepenuhnya transparan. Contoh-contoh di transparansi boolean GIF memperagakan metode untuk mengendalikan penanganan piksel semitransparan saat menyimpan ke format semacam itu.

Ringkasan

Anti-aliasing sangat penting dalam segala jenis penggambaran gambar, dan patut selalu diingat. Tanpa memperhitungkan warna campuran dan piksel semitransparan yang dihasilkan anti-aliasing IM, gambar buatan Anda sendiri bisa tampak sangat buruk pada sebagian format. Hal ini menjadi lebih penting lagi saat membuat gambar dalam format gambar yang tidak mengizinkan piksel semitransparan, seperti format "GIF" yang tersebar luas. Lihat transparansi boolean GIF untuk cara menangani masalah ini. IM sangat bagus dalam meng-anti-alias warna dan transparansi, tetapi sebenarnya sangat lemah dalam menggambar piksel 'beralias' murni saja (misalnya untuk mencocokkan peta warna tertentu). Saya diberi tahu bahwa hal itu akan menjadi fokus salah satu rilis IM berikutnya.


Menggambar hanya memakai warna tertentu

Sedang dikerjakan

Cara yang lebih baik untuk menggambar tanpa anti-aliasing, guna menghasilkan gambar dengan warna yang persis. Yaitu, untuk 'gambar indeks'. Lebih tepatnya, gambarlah ke dalam kanvas transparan, lakukan threshold pada kanal alpha, lalu overlay, sehingga hanya piksel yang sepenuhnya buram yang tergambar.


Menggambar lingkaran bitmap tipis

Di sini kita melihat upaya menggambar lingkaran bitmap 'bergaris tipis' memakai IM. Biasanya hal itu dikerjakan dengan algoritma penggambaran lingkaran bitmap yang lazim dikenal sebagai algoritma lingkaran Bresenham, tetapi lebih tepat dikenal sebagai algoritma lingkaran titik tengah. Sayangnya algoritma itu tidak tersedia di ImageMagick, dan mungkin tidak akan pernah ada karena tidak diperlukan dalam lingkungan penggambaran yang sepenuhnya ter-anti-alias. Alternatif lain untuk menggambar lingkaran, yang akan kita lihat sebentar lagi, adalah memakai morfologi untuk 'Dilate' satu piksel dengan kernel Ring khusus.
Sebagai contoh, cara normal IM menggambar lingkaran menghasilkan banyak warna anti-aliasing abu-abu supaya lingkaran itu tampak mulus. |

  magick -size 15x15 xc: -fill none -stroke black \
          -draw 'translate 7,7 circle 0,0 5,0' \
          -scale 500%  circle_antialiased.gif

[IM Output]
Namun sekadar mematikan anti-aliasing menghasilkan lingkaran dan garis yang bukan garis 'bitmap' tipis yang bagus. |

  magick -size 15x15 xc: -fill none -stroke black +antialias \
          -draw 'translate 7,7 circle 0,0 5,0' \
          -scale 500%  circle_aliased.gif

[IM Output]
Yang perlu dikerjakan adalah menyesuaikan pula "-strokewidth" , yang bawaannya selebar 1 piksel, menjadi sesuatu yang lebih kecil, misalnya selebar 0.5 piksel. |

  magick -size 15x15 xc: -fill none -stroke black +antialias \
          -strokewidth 0.5   -draw 'translate 7,7 circle 0,0 5,0' \
          -scale 500%  circle_thin_stroke.gif

[IM Output]
Lebih baik, walau belum benar-benar pas. Tetapi lebar stroke juga bisa dibuat terlalu kecil, terutama dengan radius berukuran ganjil. |

  magick -size 15x15 xc: -fill none -stroke black +antialias \
          -strokewidth 0  -draw 'translate 7,7 circle 0,0 5,0' \
          -scale 500%  circle_zero_stroke.gif

[IM Output]
Dan inilah solusi yang bagus untuk lingkaran berjari-jari 5 piksel yang berpusat tepat di lokasi piksel aktual berupa bilangan bulat. |

  magick -size 15x15 xc: -fill none -stroke black +antialias \
          -strokewidth 0.4  -draw 'translate 7,7 circle 0,0 5,0' \
          -scale 500%  circle_perfect.gif

[IM Output]
Namun setelah banyak percobaan, saya tidak menemukan "-strokewidth" yang bekerja untuk semua radius dan pusat. Terutama lingkaran yang sedikit meleset dari pusat.

Tidak ada solusi ideal untuk semua situasi

Sebagai contoh, lingkaran ini yang tidak berpusat pada piksel maupun pada batas piksel bukan hanya berlubang di bagian atas, tetapi juga terlalu tebal di bagian bawah! Payah! |

  magick -size 15x15 xc: -fill none -stroke black +antialias \
          -strokewidth 0.47  -draw 'translate 7,7.3 circle 0,0 5,0' \
          -scale 500%  circle_bad_stroke.gif

[IM Output]
Berikut tabel nilai "-strokewidth" yang bagus untuk menghasilkan lingkaran tipis selebar satu piksel dengan radius tertentu. Perhatikan bahwa nilai terbaik yang dipakai berbeda-beda tergantung apakah lingkaran itu berpusat pada piksel aktual (misalnya ' 5 , 5 ') atau pada batas setengah piksel (misalnya ' 5.5 , 5.5 ') Radius lingkaran | SW aktual | SW setengah
1 | 0.3 | 0.3 ¶
1.5 | 0.5 ¶ | 0.3
2 | 0.3 | 0.3 §
2.5 | 0.5 ¶ | 0.3 ¤
3 | 0.3 ¤ | 0.3
3.5 | 0.5 | 0.3 ¤
4 | 0.5 § | 0.3
4.5 | 0.5 | 0.3
5 | 0.4 | 0.3
5.5 | 0.5 ¶ | 0.3
6 | 0.3 | 0.5 §
6.5 | 0.5 | 0.43
7 | 0.5 | 0.434
7.5 | 0.5 § | 0.5 §
8 | 0.4 | 0.5
¤ Lingkaran kecil yang sangat bagus
§ tidak ditemukan lebar yang ideal
¶ lingkaran sangat buruk
CATATAN SAMPING: Untuk menaruh lingkaran tepat di tengah gambar, dalam koordinat penggambaran (koordinat piksel), titiknya adalah (size-1)/2


Masalah anti-aliasing dan flood fill Karena fitur anti-aliasing IM, flood-fill ("-draw color floodfill") bermasalah bila dipakai pada gambar yang punya efek anti-aliasing. Masalah serupa juga muncul pada gambar yang dibaca dari format gambar "JPG". Pada dasarnya, karena kebanyakan objek di IM ter-anti-alias (atau dibaca dari file gambar berformat "JPG"), warna di dekat tepi objek yang digambar jarang persis sama dengan warna tertentu yang hendak Anda ganti lewat flood fill. Artinya flood fill tidak akan mengisi tepi terluar area yang hendak diisi, kecuali bila anti-aliasing dihindari sama sekali. Pada intinya flood fill, bahkan color replace sekalipun, tidak memahami anti-aliasing dan juga tidak memakai teknik anti-aliasing sendiri. Akibatnya flood fill umumnya melewatkan piksel di tepi terluar area yang diisi. Sebagai contoh, di sini kita melakukan operasi flood fill yang khas. Gambarlah sebuah lingkaran, lalu cobalah mengisinya dengan pola... |

    magick -size 60x60 xc:lightblue -strokewidth 2 \
            -fill none -stroke red -draw "circle 30,30 5,30" \
            -tile tile_weave.gif  -draw "color 30,30 floodfill" \
            tile_fill_1.gif
    magick tile_fill_1.gif -crop 10x10+35+4 +repage -scale 80x80 \
            tile_fill_1_mag.gif

[IM Output] [IM Output]
Seperti terlihat pada bagian gambar yang diperbesar, satu garis piksel 'salah warna' sepenuhnya terlewat oleh operasi flood fill, sebab warna piksel-piksel itu tidak persis sama dengan area yang sedang diisi. Salah satu cara memperbaikinya adalah mengisi lebih dulu area yang hendak diisi dengan warna yang serasi dengan pola yang dipakai. Polanya tetap tidak akan mengisi area itu sepenuhnya, tetapi setidaknya hasilnya tidak terlalu buruk. |

    magick -size 60x60 xc:lightblue -strokewidth 2 \
            -fill black -stroke red  -draw "circle 30,30 5,30" \
            -tile tile_weave.gif  -draw "color 30,30 floodfill" \
            tile_fill_2.gif
    magick tile_fill_2.gif -crop 10x10+35+4 +repage -scale 60x60 \
            tile_fill_2_mag.gif

[IM Output] [IM Output]
Cara lain adalah mengisi area itu dengan pola Anda, memakai faktor fuzz yang tinggi , untuk memaksa pola itu mengisi area secara penuh sampai ke tepi terluar, tanpa melewatkan piksel tepi. |

    magick -size 60x60 xc:lightblue -strokewidth 2 \
            -fill none -stroke red  -draw "circle 30,30 5,30" \
            -fuzz 35% -tile tile_weave.gif -draw "color 30,30 floodfill" \
            tile_fill_3.gif
    magick tile_fill_3.gif -crop 10x10+35+4 +repage -scale 60x60 \
            tile_fill_3_mag.gif

[IM Output] [IM Output]
| Perhatikan bahwa 'faktor fuzz' setinggi ini, atau garis tepi yang terlalu tipis, dapat membuat pola isian 'bocor' keluar dari area yang ditentukan. Berhati-hatilah selalu saat memakai operasi flood-fill. Justru karena hal ini, saya sendiri tidak merekomendasikannya sebagai solusi umum.
Masalahnya, karena flood fill menurut sifatnya memang TIDAK memakai anti-aliasing, tepi area yang terisi menderita efek 'jaggies' atau alias. Situasi itu bisa diperbaiki dengan memisahkan penggambaran gambar menjadi beberapa langkah tersendiri. Buat lingkaran berwarna, isi, lalu gambar garis tepinya. |

    magick -size 60x60 xc:lightblue -fill black -draw "circle 30,30 5,30" \
            -tile tile_weave.gif -draw "color 30,30 floodfill" +tile \
            -fill none -stroke red  -strokewidth 2 -draw "circle 30,30 5,30" \
            tile_fill_4.gif
    magick tile_fill_4.gif -crop 10x10+35+4 +repage -scale 60x60 \
            tile_fill_4_mag.gif

[IM Output] [IM Output]
Ini satu cara sederhana untuk memperbaiki flood fill. Cara lainnya adalah memakai overlay berbentuk, tetapi metode itu bisa rumit untuk dirancang. Nanti saya akan melihat modifikasi serupa pada gambar yang sudah ada. Tentu saja, kalau area yang di-flood fill itu Anda gambar sendiri dan bukan memakai gambar yang sudah ada, solusi idealnya adalah menghindari flood fill dengan menentukan pola isian pada operasi penggambaran aslinya. |

    magick -size 60x60 xc:lightblue -strokewidth 2 \
            -tile tile_weave.gif -stroke red -draw "circle 30,30 5,30" \
            tile_fill_5.gif
    magick tile_fill_5.gif -crop 10x10+35+4 +repage -scale 60x60 \
            tile_fill_5_mag.gif

[IM Output] [IM Output]


FUTURE:  anti-aliasing issues on pre-exsiting images (especially JPG format).

For Example Recoloring and overlaying text or diagram image onto a color
or background.

Also re-adding transparency to GIF files, and rescaled JPEGs for icon use.

**Smoothing or anti-alising images with limited color set**
Specifically bitmap (pure black and white) images.

First anti-aliasing does not work on bitmap images.

Anti-aliasing involves using a mix of colors and transparences to try and
smooth the 'stair case' or 'jaggies' effect of slanted lines and color
boundaries.  If only two colors are available no anti-aliasing can NOT happen!

The image must be converted from B&W or grey scale at the minimum before
anti-aliasing can be used.

A simple way to smooth edges is to use a small amount of blur after reading in
a B&W image or an image with a tiny pallette size.

EG:   magick image.xbm  -blur 0x.3  smoothed_image.png