Monday, July 11, 2011

C# ASCII Art Generator

imageASCII art dapat dikatakan sebagai suatu bentuk seni yang dihasilkan oleh komputer yang mampu mengubah suatu gambar menjadi kumpulan karakter yang berasal dari 95 total karakter ASCII komputer yang dapat di print. Dan karakter-karekter tersebut disusun sedemikian rupa sehingga, jika dilihat dari jauh atau ukuran fontnya diperkecil akan membentuk suatu gambaran tertentu. Ada beberapa macam ASCII art, seperti :
imageimage
image
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.
Untitled
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
C# :
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
image

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