Tetapi yang akan dibahas dalam postingan kali ini adalah pembuatan ASCII Art dalam bentuk Newskool Style. Dimana sebuah gambar akan diubah menjadi tumpukan karakter tertentu.
Algoritma
Algoritma pembuatan ASCII Art jenis ini sebenarnya sangat mudah. Anda cukup membayangkan bahwa suatu gambar sebenarnya adalah array 2 dimensi yang berisi nilai warna setiap pixel. Pixel adalah satuan terkecil dalam penyimpanan suatu gambar di komputer yang mewakili warna. Warna dalam komputer dibentuk dari 3 komponen ( RGB ), sehingga, tiap pixel mengandung 3 angka yang menentukan derajat terang dari 3 warna ( Merah-Hijau-Biru / RGB ). Dari ketiga nilai inilah, maka setiap pixel dapat memiliki warna. Nilai RGB setiap pixel bervariasi dari 0-255. Sehingga hasil rata-rata ketiganya tidak mungkin melebihi 255 atau kurang dari 0.
Array 2 dimensi yang berisi pixel ini dapat di analogikan dengan persegi. Lalu, bagi persegi tersebut dalam persegi yang lebih kecil lagi. Nantinya akan ada sebuah akrakter yang mewakili persegi kecil ini. Untuk menentukan karaktrer yang mana, hitung rata-rata nilai seluruh pixelnya. Hasil rata-rata ini lalu dicocokan dengan karakter mana yang akan kita pakai.
Karakter apa yang akan dipakai?
Sebelumnya kita harus mempunyai daftar(array) code ASCII dari karakter yang akan kita gunakan, dan harus diurutkan dari yang paling ‘gelap’ sampai yang paling ‘terang’. Pengurutan yang dilakukan oleh penulis di bawah ini masih belum sempurna sebenarnya, masih ada beberapa karakter yang tidak sesuai dengan kenyataan.Jika anda mau anda dapat mengubah sendiri susunan ini sesuai dengan selera. Daftar kode ASCII dari karakter-karakter ini dapat dilihat di ASCII Printable Characters di http://en.wikipedia.org/wiki/ASCII
Pseudocode
- Deklarasikan gambar beserta array integer berisi kode karakternya (ASCII). Dalam C# gambar dibuka oleh openFileDialog dari toolbox dan disimpan dalam object dari class Bitmap ( using System.Drawing.Bitmap )
- Siapkan sebuah textbox dari toolbox. Ganti propertinya sehingga mendukung multiline dan ganti fontnya dengan jenis monospace. (Courier New, Consolas, dll) tentunya dengan ukuran yang kecil ( 5-8pt )
- Bagi gambar menjadi kotak-kotak kecil dengan ukuran tertentu. Untuk setiap kotak, cari rata-rata dari semua pixel di sana. ( Gunakan for, dan fungsi )
- Cocokan dengan daftar karakter yang ada, makin besar angkanya, berarti makin ‘ terang’
- Tambahkan karakter dalam properti text dari textbox
Dalam contoh kali ini, digunakan 25 karakter ASCII. Diurutkan mulai dari paling ‘gelap’ hingga paling ‘terang’. Karena nilai rata-rata hanya akan bervariasi antara 0 – 255 dan terdapat 25 karakter, maka tiap karakter memiliki jangkauan 10. Misal, fungsi getValue menghasilkan angka 123, maka karakter yang di print adalah ‘2’.
Maka susunannya akan menjadi :
Karakter
|
Kode ASCII
|
Mulai dari
|
Sampai dengan
|
35 | # | 240 | 250 |
77 | M | 230 | 240 |
78 | N | 220 | 230 |
64 | @ | 210 | 220 |
37 | % | 200 | 210 |
38 | & | 190 | 200 |
36 | $ | 180 | 190 |
56 | 8 | 170 | 180 |
57 | 9 | 160 | 170 |
54 | 6 | 150 | 160 |
52 | 4 | 140 | 150 |
51 | 3 | 130 | 140 |
50 | 2 | 120 | 130 |
48 | 0 | 110 | 120 |
49 | 1 | 100 | 110 |
63 | ? | 90 | 100 |
40 | ( | 80 | 90 |
59 | ; | 70 | 80 |
33 | ! | 60 | 70 |
58 | : | 50 | 60 |
46 | . | 40 | 50 |
32 | space | 30 | 40 |
32 | space | 20 | 30 |
32 | space | 10 | 20 |
32 | space | 0 | 10 |
Berikut adalah fungsi utama, generateASCII() yang akan menjadi inti dari program ini :
private void generateASCII() { if (gambar != null) { string kata = ""; for (int y = 0; y < gambar.Height / packetSize; y++) { for (int x = 0; x < gambar.Width / packetSize; x++) { int rata2kotak = getValue(x, y); kata += char.ConvertFromUtf32(assignedChar(rata2kotak)); } kata += Environment.NewLine; } textBox1.Text = kata; } }packetSize adalah variabel yang menentukan besarnya ‘ kotak kecil’ atau besarnya potongan yang anda pakai, semakin besar nilainya semakin sedikit karakter yang dihasilkan nantinya.
gambar adalah object dari class Bitmap yang sudah berisi gambar. Ada 2 parameter yang digunakan Lebar(Width) dan tinggi(Height) gambar dalam pixel.
getValue adalah fungsi/method buatan sendiri yang akan menghitung rata-rata nilai pixel dalam setiap potongan. Memiliki inputan berupa koordinat dari kotak kecil.
private int getValue(int x, int y) { int returnedResult = 0; for (int j = packetSize * y; j < (y + 1) * packetSize - 1; j++) { for (int i = packetSize * x; i < (x + 1) * packetSize - 1; i++) { Color warna = gambar.GetPixel(i, j); returnedResult += (warna.R + warna.G + warna.B) / 3; } } returnedResult /= packetSize * packetSize; return returnedResult; }enambahkan sebuah karakter dalam textbox, diperlukan method ConvertFromUtf32( int ) dari class Char. Sebagai parameter, adalah kode ASCII yang hendak di print ( decimal ). Dalam contoh ini, kode ASCII tersebut didapat dari fungsi assignedChar(int) yang dibuat sendiri nanti.
assignedChar adalah fungsi yang akan menghasilkan code ASCII dari nilai rata-rata semua pixel dari ‘potongan’ atau ‘kotak kecil’ itu, yang didapat dari method getValue().
int assignedChar(int angka) { for (int x = 0; x < 25; x++) { if (angka >= x * 10 && angka < (x + 1) * 10) return daftarChar[x]; } return 32; }
daftarChar adalah array angka ( integer ) yang berisi daftar kode ascii karakter yang paling gelap hingga yang paling terang.
Pada setiap akhir dari suatu baris ( alias setiap akhir dari for terdalam ), character harus ditambah dengan karakter enter. Tetapi semenjak kita menggunakan C#, hanya diperlukan variabel NewLine dari class System.Environment
Demo
Download Source
Dalam demo ini trackbar berlabel ‘besar’, menentukan besarnya variable packetSize dengan kata lain menentukan besarnya gambar yang akan dihasilkan dan detail dari gambar itu. Selamat mencoba!
No comments:
Post a Comment