Kamis, 22 September 2011

Komputer Grafik

PENGANTAR
Penggambaran grafik garis lurus dan kurva memerlukan waktu komputasi yang tinggi, untuk mereduksi waktu komputasi yang tinggi tersebut dapat dilakukan dengan peningkatan kemampuan komputasi prosesor dan peningkatan efisiensi algoritma. Algoritma Midpoint merupakan Algoritma dengan dasar operasi bilangan integer, sehingga memerlukan waktu operasi yang lebih sedikit dibandingkan dengan algoritma yang menggunakan operasi bilangan real. Implementasi ke dalam bahasa pemrograman C dari kedua macam algoritma diatas, menunjukkan bahwa waktu komputasi algoritma midpoint lebih cepat sebesar 8 kali pada pembuatan garis lurus, dan lebih cepat sebesar 15 kali pada penggambaran lingkaran, dibandingkan dengan waktu komputasi algoritma yang menggunakan dasar operasi bilangan
riel. Dan waktu komputasi algoritma midpoint lebih cepat sebesar 6 kali pada pembuatan garis lurus, dibandingkan dengan waktu komputasi algoritma yang Breserham telah menggunakan dasar operasi bilangan integer juga.
Algoritma DDA
1. Start at first endpoint.
2. Draw pixel.
3. Step right by one pixel and up by m*change_in_x
1. (But change_in_x is 1 pixel!
2. so just step up by m pixels)
4. Draw pixel.
5. Repeat from step 3, until we reach second endpoint
Pseudo code:
1. Let x = x1; y = y1; m = (y2-y1)/(x2- x1);
2. Draw pixel (x, y)
3. WHILE (x < x2) //i.e. we reached the second endpoint
{
x = x + 1; //step right by one pixel
y = y + m; //step up by m pixels
Draw pixel (ROUND(x), ROUND(y));
}
Banyak yang menganggap bahwa algoritma DDA sangat lambat didalam menggambarkan suatu titik, garis maupun kurva. Berikut ini adalah function untuk menggambar garis dengan algoritma DDA
int line_dda(int x1,int y1,int x2,int y2,int color)
// Algorithm digital differential analyzer
{ int dx,dy,step,k;
float x_increment,y_increment,x,y;
dx = x2-x1; dy = y2-y1;
// determine maximum step
if (abs(dx) > abs(dy)) step=abs(dx); else step=abs(dy);
x_increment = float(dx) / float(step);
y_increment = float(dy) / float(step);
x = x1; y = y1;
putpixel(int (x+0.5),int(y+0.5),color);
for (k=1;k<=step;k++)
{ x = x+x_increment;
y = y+y_increment;
putpixel(int(x+0.5),int(y+0.5),color);
}
return(0);
}
Garis lurus dinyatakan dinyatakan dalam persamaan :
y = mx + c (1)
dimana : m : gradient dan c : konstanta.
Untuk menggambarkan pixel-pixel dalam garis lurus, parameter yang digunakan tergantung dari gradient, jika besarnya gradient diantara 0 dan 1, maka digunakan sumbu x sebagai parameter dan sumbu y sebagai hasil dari fungsi, sebaliknya, bila gradient melebihi 1, maka sumbu y digunakan sebagai parameter dan sumbu x sebagai hasil dari fungsi, hal ini bertujuan untuk menghindari terjadinya gaps karena adanya pixel yang terlewatkan. Hasil dari fungsi biasanya merupakan bilangan real, sedangkan koordinat pixel dinyatakan dalam bilangan integer (x,y), maka diperlukan operasi pembulatan kedalam bentuk integer terdekat. Penggambaran garis lurus dengan metode diatas dimulai dengan operasi bilangan real untuk menghitung gradient m dan konstanta c.
m = (y2 - y1 ) / (x2-x1) (2)
c = y1 – m* x1 (3)
Operasi bilangan real berikutnya adalah menghitung nilai y dengan persamaan (1) untuk mendapatkan koordinat piksel (x,y), untuk setiap nilai x, dari =x1 sampai x=x2, operasi inilah yang perlu dihindari, karena operasi ini memerlukan waktu operasi yang besar.
Algoritma Bresenham
Bresenham pada tahun 1965, melakukan perbaikan dari algoritma perhitungan koordinat piksel yang menggunakan persamaan (1), dengan cara menggantikan operasi bilangan riel perkalian dengan operasi penjumlahan, yang kemudian dikenal dengan Algoritma Bresenham. Pada algoritma bresenham, nilai y kedua dan seterusnya, dihitung dari nilai y sebelumnya, sehingga hanya titik y pertama yang perlu dilakukan operasi secara lengkap. Perbaikan algoritma ini ternyata tidak menghasilkan perbaikan yang cukup siginifikan. Perbaikan berikutnya dilakukan dengan cara menghilangkan operasi bilangan real
dengan operasi bilangan integer. Operasi bilangan integer jauh lebih cepat dibandingkan dengan operasi bilangan real, terutama pada penambahan dan pengurangan.
int line_bre(int x1,int y1,int x2,int y2,int color)
// Algorithm Bresenham
{ int dx,dy,x,y,x_end;
int p,const1,const2;
dx = x2-x1; dy = y2-y1;
p = 2*dy-dx; y = y1;
const1 = 2*dy; const2 = 2*(dy-dx);
// determine which point to use as start, which as end
if (x1 > x2)
{ x = x2; y = y2; x_end = x1; }
else
{ x = x1; y = y1; x_end = x2; }
putpixel(x,int(y+0.5),color);
while ( x < x_end )
{ x++;
if ( p < 0 )
p = p+const1;
else
{ y = y+1;
p = p+const2;
}
putpixel(x,int(y+0.5),color);
}
return(0);
}
KOMPUTER GRAFIK DENGAN QUICK BASIC
Quick Basic adalah bahasa pemrograman high level yang cukup terstruktur, walaupun mengijinkan beberapa lompatan didalam struktur programnya. Untuk komputer grafik, Quick Basic menyediakan perintah-perintah yang cukup mudah dan sederhana, tentunya untuk menghasilkan output grafik yang sederhana. Quick Basic adalah compiler, sama seperti Turbo Pascal ataupun Borland C++, jadi jika memang diperlukan, Quick Basic mampu mengkompilasi program Basic menjadi program executable.
Mode Grafis di dalam Quick Basic
Di dalam Quick Basic, inisialisasi mode grafis, cukup dengan memberikan sebuah perintah SCREEN yang diikuti dengan bilangan integer. Berikut ini adalah mode SCREEN yang sering digunakan dalam pemrograman grafis
SCREEN 0 : mode teks, dipanggil untuk mengakhiri mode grafis
SCREEN 1 : mode grafis resolusi rendah 320x200 pixel, maksimum 4 warna
SCREEN 12 : mode grafis resolusi tinggi 640x480 pixel, maksimum 16 warna
SCREEN 13 : mode grafis resolusi rendah 300x200 pixel, maksimum 256 warna. Mode grafis ini yang sering digunakan dalam pemrograman animasi ataupun game pada era DOS
' ACAX Experiment Program
SCREEN 12
CLS
LINE (1, 1)-(640, 480), 1, BF
LINE (30, 30)-(610, 450), 0, BF
Ulang:
x1 = RND * 575 + 35
x2 = RND * 550 + 35
x2 = (x1 - x2) / 3 + x2
y1 = RND * 350 + 55
y2 = 450
LINE (x1, y1)-(x2, y2), RND * 6 + 1, BF
LINE (x1, y1)-(x2, y2), 0, B
FOR Delay = 1 TO 800
NEXT
IF INKEY$ = CHR$(13) THEN
SCREEN 0
END
END IF
GOTO Ulang
Program diatas akan menggambar kotak dengan warna dan posisi serta ukuran random. Jika anda lihat program Quick Basic diatas, akan terlihat bahwa program tersebut akan diulang terus dengan adanya perintah GOTO Ulang. Program akan berhenti jika kita menekan tombol keyboard ENTER sebagaimana diberikan dari perintah IF INKEY$=CHR$(13) adalah pengecekan terhadap penekanan tombol ENTER
Perintah-perintah grafik Quick Basic
Perintah-perintah dasar di dalam komputer grafik pada dasarnya hampir sama antara bahasa pemrograman yang satu dengan lainnya.
Apa yang dimaksud dengan pixel? Pixel adalah satu titik yang ada di layar monitor, sedangkan resolusi adalah kumpulan pixel yang membentuk suatu gambar atau dapat juga dikatakan kumpulan total dari pixel-pixel.
Perintah PSET dan PRESET, berfungsi menghidupkan / mematikan pixel pada posisi koordinat tertentu.
Perintah LINE akan menggambar garis diawali dari posisi x1,y1 sampai dengan x2,y2. Berikut adalah Rumus Perintah LINE;
LINE (x1,y1) - (x2,y2), color
dimana color atau warna akan sangat bergantung pada mode grafik yang anda gunakan. Pada mode grafis tertentu, dikenal sistem palette dimana kita dapat mencampur warna dan menghasilkan variasi warna yang sangat banyak.
Perintah CIRCLE, dapat digunakan untuk menggambar lingkaran ataupun kurva sesuai dengan nilai yang kita masukkan.
Beberapa perintah dasar grafik yang lainnya akan dapat dengan mudah dipelajari di dalam Help Quick Basic.
' Gambar Kuas Cat
SCREEN 1
CLS
x = 200
y = 175
COLOR 0, 1
CIRCLE (x - 122, y - 118), 3, 3, , , 1
CIRCLE (x - 135, y - 25), 100, 3, .9, 1.6, 1
CIRCLE (x - 66, y - 193), 100, 3, 3.9, 4.68, 1
CIRCLE (x - 80, y - 64), 30, 3, , 1.4, 1
CIRCLE (x - 51, y - 124), 30, 3, 3.9, 5.5, 1
PSET (x - 50, y - 63), 3
DRAW "m+6,+2m+20,-40nm-6,-2m+18,+6m-20,+40m-18,-6"
DRAW "m+60,+20m+20,-40m-60,-20"
PAINT (x - 47, y - 65), 3
PAINT (x - 37, y - 65), 1, 3
CIRCLE (x - 66, y - 193), 100, 2, 3.9, 4.68, 1
CIRCLE (x - 80, y - 64), 30, 2, , 1.4, 1
PSET (x - 44, y - 61), 0
DRAW "nm+20,-40br14bd6nm+22,-44bl4m+22,-44"
a$ = INPUT$(1)
WIDTH 80
SCREEN 0
END
Program diatas akan menggambar sebuah kuas cat di layar. Yang perlu diperhatikan adalah perintah DRAW sangat bermanfaat dalam menggambar suatu object dengan bentuk yang tidak beraturan. Bandingkanlah dengan program berikut:
' Candle Picture using Statement DRAW
SCREEN 1
CLS
x = 160
y = 148
COLOR 0, 0
CIRCLE (x + 15, y - 26), 20, 3, , , 1
CIRCLE (x + 15, y - 26), 14, 3, , , 1
PAINT (x + 15, y - 10), 2, 3
CIRCLE (x - 53, y - 20), 20, 3, 4.8, .3, .6
CIRCLE (x + 9, y - 20), 20, 3, 2.84, 4.6, .6
PRESET (x - 35, y - 24), 3
DRAW "l2h2u2e2r30f2d2g2l3"
PRESET (x - 56, y - 1), 3
DRAW "h2u2e2r5br60r5f2d2g2l70"
PAINT (x - 48, y - 3), 2, 3
DRAW "bu5c3r52bu15bl15l22"
PRESET (x - 32, y - 31), 1
DRAW "nr20u35g2l1u2e2u14m+22,-5f2d13f1d2g1l1h1d38"
PAINT (x - 30, y - 35), 1
PRESET (x - 32, y - 65), 0
DRAW "e1u5e1u3f2d8g1d1f1r3u7e2u1e1u6e1f1r2e1u1h1r2f2r2d7"
PRESET (x - 22, y - 88), 3
DRAW "u4"
a$ = INPUT$(1)
WIDTH 80
SCREEN 0
END
Program diatas akan menggambarkan sebuah lilin. Jika kita perhatikan, kedua program tersebut menggunakan mode screen 1, yang hanya dapat menampilkan 4 warna, tetapi karena sistem palette yang didapat dari perintah COLOR, maka warna yang dihasilkan dari program pertama berbeda dengan program kedua. Sedangkan perintah PAINT, digunakan untuk mengisi ruang yang kosong dengan warna tertentu. Bereksperimen dengan perintah-perintah grafik akan dapat membantu untuk menghasilkan bentuk-bentuk gambar yang menarik.
Rumus perintah DRAW
DRAW commandstring$
dimana commandstring$ adalah ekspresi yang berisi kumpulan perintah DRAW sbb;
Perintah menggambar garis dan memindah kursor
D[n%] Memindah kursor ke arah selatan sebanyak n% units.
E[n%] Memindah kursor ke arah timur laut sebanyak n% units.
F[n%] Memindah kursor ke arah tenggara sebanyak n% units.
G[n%] Memindah kursor ke arah barat daya sebanyak n% units.
H[n%] Memindah kursor ke arah barat laut sebanyak n% units.
L[n%] Memindah kursor ke arah barat sebanyak n% units.
M[{+|-}]x%,y% Memindah kursor ke koordinat (x%,y%).
R[n%] Memindah kursor ke arah barat sebanyak n% units.
U[n%] Memindah kursor ke arah utara sebanyak n% units.
Setelah mempelajari beberapa perintah dasar komputer grafik pada Quick Basic, anda dapat mempraktekkan dengan menggambar bentuk-bentuk sesuai keinginan anda.
TEORI DASAR ANIMASI
Apa yang dimaksud dengan Animasi? Tentunya kita sering mendengar istilah animasi yang biasa dikaitkan dengan film kartun. Secara gampang, animasi adalah object yang bergerak. Jika kita belajar komputer grafik, kita tidak hanya belajar menciptakan gambar-gambar object yang statis, tetapi kita juga belajar bagaimana membuat object-object tersebut bergerak. Hal inilah yang disebut dengan animasi.
Animasi di dalam Quick Basic ataupun pada program lainnya secara umum dapat dilihat dari algoritma sebagai berikut:
1. Gambar object yang akan dianimasikan
2. Simpan ke dalam variabel
3. Letakkan pada posisi awal
4. Hapus object
5. Letakkan pada posisi baru
6. Ulangi langkah no. 4 sampai selesai
Jadi pada dasarnya animasi pada komputer grafik adalah menghapus gambar pada posisi lama dan menggambar di posisi baru, demikian seterusnya. Karena kecepatan proses komputer, maka semuanya akan terlihat seolah-olah bergerak. Yang perlu diperhatikan adalah object yang dianimasikan harus benar-benar sama, jika tidak maka animasinya tidak akan terlihat bagus.
Berikut adalah contoh program animasi dengan kontrol keyboard
'Mendefiniskan Tipe Integer untuk semua variabel yang digunakan
DEFINT A-Z
'Membersihkan layar
CLS
'Inisialisasi Grafik, Screen 1 = CGA 320x200 4 warna
SCREEN 1
'Mengeset Warna
COLOR 0, 0
'Memesan array untuk Sprites
DIM nob(39)
'Looping untuk membaca data-data gambar
FOR i = 0 TO 39
READ nob(i)
NEXT
'Data-data gambar Sprite
DATA 32
DATA 14,20481,16389,22277,20693,1797,4308,1797,4308,24321
DATA 16629,-256,255,15360,60,-29694,-32718,3850,-24336,778,-24384,10
DATA -24576,10,-24576,-32726,-22526,-24406,-22006,0,0,0,0,0,0,0,0,0,0
'Posisi Koordinat Awal Sprite
xpos = 150: ypos = 150
'Gerakan Sprite per pixel
xofset = 2: yofset = 2
'Munculkan Sprite di Layar
PUT (xpos, ypos), nob
main.loop:
'Simpan nilai xpos dan ypos
old.xpos = xpos
old.ypos = ypos
'Baca Keyboard Buffer
keyb$ = INKEY$
'Jika tidak ada yang ditekan, lompat ke main.loop
IF keyb$ = "" THEN GOTO main.loop
'Jika ada yang ditekan, lompat ke subrutin cek.button
GOSUB cek.button
'Rutin berikut ini untuk pengecekan batas layar
GOSUB cek.batas
'Letakkan Sprite di posisi lama untuk menghapus sprite
PUT (old.xpos, old.ypos), nob, XOR
'Gambar lagi Sprite di posisi koordinat baru
PUT (xpos, ypos), nob, XOR
'lompat lagi ke main.loop
GOTO main.loop
'Rutin pengecekan batas layar agar tidak ERROR
cek.batas:
IF xpos < 1 THEN xpos = 300
IF xpos > 300 THEN xpos = 1
IF ypos > 185 THEN ypos = 5
IF ypos < 5 THEN ypos = 185
RETURN
'Rutin pengecekan tombol keyboard
cek.button:
'Jika panjang keyboard code tidak sama dengan 2, artinya bukan arrowkey
'lompat ke not.arrow
IF LEN(keyb$) <> 2 THEN GOSUB not.arrow
‘Ambil karakter yang kedua
keyb = ASC(RIGHT$(keyb$, 1))
‘cek tombol atas
IF keyb = 72 THEN ypos = ypos – yofset
‘cek tombol kiri
IF keyb = 75 THEN xpos = xpos – xofset
‘cek tombol kanan
IF keyb = 77 THEN xpos = xpos + xofset
‘cek tombol bawah
IF keyb = 80 THEN ypos = ypos + yofset
not.arrow:
‘Jika ditekan tombol q maka program akan berhenti
IF keyb$ = “q” THEN
WIDTH 80
SCREEN 0
COLOR 7, 0
CLS
END
END IF
RETURN
Contoh program animasi diatas cukup rumit dengan adanya tambahan rutin untuk menggerakkan object dengan tombol keyboard, yang umumnya adalah tombol arrow key, disamping itu kita juga harus mengecek dan memeriksa penekanan tombol q dimana program akan berhenti apabila tombol q ditekan. Dan akhirnya, penambahan rutin untuk mendeteksi batas layar, yaitu batas atas, bawah, kiri dan kanan. Jika kita perhatikan, untuk gambar objectnya menggunakan perintah READ dan DATA yang diikuti sekumpulan angka dan bilangan. Pada pertemuan berikutnya akan dibahas tentang program untuk menggambar bentuk-bentuk object secara mudah, dimana output dari program tersebut berupa file dengan kumpulan bilangan-bilangan seperti pada program diatas.
Pengertian Sprite di dalam Komputer Grafik
Jika anda mendengar istilah sprite dalam komputer grafik, yang dimaksud adalah object untuk animasi. Agar dapat dianimasikan, sprite harus disimpan di dalam suatu variabel array, yang di dalam Quick Basic dideklarasikan dengan perintah DIM.
Menghitung ukuran sprite yang disimpan
Ukuran sprite yang disimpan akan memakan tempat di memory. Oleh karena itu, kita harus dapat menghitung dengan tepat, ukuran variabel array yang digunakan untuk menyimpan sprite tersebut. Sebelum kita dapat menghitung, kita perlu mengetahui bahwa beberapa parameter untuk setiap mode grafik memiliki nilai yang berbeda. Dalam hal ini kita akan membandingkan mode grafik SCREEN 1, 12 dan 13
Mode Grafik Bits-per-pixel-per-plane Planes Resolusi
SCREEN 1 2 1 320×200
SCREEN 12 1 4 640×480
SCREEN 13 8 1 320×200
Adapun formula atau rumusnya adalah sebagai berikut;
size% = 4 + INT(((PMAP (x2!, 0) – PMAP (x1!, 0) + 1) *
(bits-per-pixel-per-plane%) + 7) / 8) * planes% *
(PMAP (y2!, 1) – PMAP (y1!, 1) + 1)
Setelah kita dapatkan nilai size / ukurannya, maka kita langsung masukkan nilai tersebut dengan menggunakan perintah DIM, contoh:
DIM sprite(size%)
Sedangkan looping pembacaan data gambarnya, haruslah diawali dari 0 sampai dengan nilai size% yang sudah didapatkan.
COLLISION DETECTION
Disebut juga Deteksi Tubrukan. Yang dimaksud dengan tubrukan disini adalah pertemuan antara sprite yang satu dengan lainnya. Jika kita sudah mampu membuat animasi sprite, tentunya kita akan mencoba memasukkan lebih dari satu sprite ke layar. Collision Detection digunakan untuk mendeteksi apa yang harus dikerjakan jika sprite-sprite bertemu atau bertubrukan. Suatu contoh, apabila kita memiliki 3 buah sprite A, B dan C. Keadaan yang terjadi pada saat sprite A menubruk sprite B mungkin akan berbeda dengan keadaan yang terjadi apabila sprite B menubruk sprite C. Collision Detection akan memberi signal kepada kita dan dapat memilah-milah sprite mana yang sedang bertubrukan. Collision Detection akan sangat bermanfaat dalam Teknik Simulasi ataupun dalam aplikasi program permainan.
Metode Deteksi Tubrukan
Sebenarnya ada beberapa metode, tetapi yang akan dibahas disini ada tiga yaitu;
Metode Posisi Absolut
Metode ini akan menentukan satu atau beberapa posisi koordinat absolut pada layar, sehingga apabila ada sprite yang menubruk posisi ini, akan dijalankan rutin tubrukan.
Kelemahan:
* Memboroskan memory apabila menggunakan multi-screen, karena kita akan mengecek berulang-ulang
* Sulit membedakan sprite yang menubruk posisinya
Metode Pengecekan Warna
Metode ini akan mengecek, jika warna di sekelilingnya masih 0 (hitam), maka tubrukan belum terjadi. Sebaliknya jika tidak sama dengan 0, maka tubrukan terjadi.
Kelemahan:
* Hanya bisa digunakan untuk layar dengan latar belakang gelap
Metode Target Index
Metode ini akan membagi satu layar menjadi beberapa cell atau komponen. Untuk beberapa program permainan arcade sederhana, metode ini cukup akurat digunakan untuk mendeteksi tubrukan, dan metode ini juga bisa membedakan jenis-jenis sprite yang mengalami tubrukan dan rutin tubrukan yang akan dijalankan apabila terjadi tubrukan.
Mode Grafik 13 Heksa
Pada era DOS tahun 90-an, mode grafik ini sangat populer digunakan dalam program permainan yang populer saat itu. Perusahaan Game berlomba-lomba meluncurkan game-game 2 Dimensi dengan latar belakang yang bagus (pada saat itu) karena mampu menampilkan variasi warna sebanyak 256 warna. Hal ini tentunya sangat menyenangkan dan merupakan terobosan pada saat itu setelah Nintendo yang juga sukses meluncurkan game 16 warnanya. Mode Grafik ini dipilih karena bagus dan cepat. Game-game animasi saat itu ditulis dengan menggunakan bahasa pemrograman C yang terkenal dengan bahasa pemrograman tingkat menengah, masih dekat dengan bahasa manusia, tetapi memiliki kemampuan berinteraksi langsung dengan mesin yang cukup canggih.
Mode Grafis 13 Heksa dimulai pada alamat segmen memory A000:0000, sedangkan pada Quick Basic, anda cukup menginisialisasi mode grafik ini dengan memberikan satu perintah sederhana SCREEN 13. Dengan Mode Grafik ini, kita dapat menghasilkan gambar yang cukup bagus. Program berikut akan menampilkan gambar tengkorak yang cukup bagus;
DEFINT A-Z
SCREEN 13
CLS
DIM Face4(715)
FOR i = 0 TO 715
READ Face4(i)
NEXT
LINE (88, 8)-(121, 56), 15, B
PUT (90, 10), Face4
a$ = INPUT$(1)
WIDTH 80
COLOR 7, 0
CLS
‘Data IV
DATA 240 , 45 , 0 , 0 , 0 , 2305 , 1 , 0 , 0 , 0
DATA 0 , 256 , 2357 , 2313 , 1 , 0 , 0 , 0 , 0 , 257
DATA 2305 , 0 , 0 , 0 , 0 , 0 , 0 , 13577 , 265 , 257
DATA 0 , 0 , 0 , 0 , 257 , 309 , 0 , 0 , 1542 , 1542
DATA 6 , 0 , 13569 , 2305 , 1 , 1 , 0 , 0 , 0 , 2305
DATA 9 , 0 , 1542 , 1542 , 1542 , 1542 , 0 , 13568 , 257 , 265
DATA 0 , 0 , 0 , 256 , 13569 , 1 , 1536 , 1542 , 16646 , 16961
DATA 1601 , 6 , 2304 , 265 , 2305 , 0 , 0 , 0 , 256 , 13577
DATA 0 , 1542 , 16961 , 16706 , 16963 , 16706 , 6 , 256 , 309 , 257
DATA 1 , 0 , 0 , 256 , 2357 , 0 , 16646 , 16962 , 16962 , 17218
DATA 16963 , 1601 , 0 , 2357 , 1 , 1 , 0 , 0 , 2304 , 309
DATA 1536 , 16961 , 16962 , 16962 , 3855 , 17219 , 1601 , 0 , 13577 , 257
DATA 256 , 0 , 0 , 13569 , 9 , 1536 , 1601 , 16902 , 16706 , 3855
DATA 17217 , 16707 , 6 , 13569 , 265 , 1 , 0 , 256 , 2305 , 1
DATA 16646 , 16646 , 1602 , 3846 , 16911 , 3855 , 16963 , 6 , 2304 , 309
DATA 257 , 0 , 256 , 265 , 0 , 16902 , 16705 , 3855 , 1551 , 1551
DATA 16911 , 16963 , 1601 , 256 , 2357 , 257 , 0 , 2305 , 257 , 0
DATA 1542 , 16962 , 17219 , 16963 , 3905 , 17167 , 17217 , 1602 , 256 , 13569
DATA 257 , 1 , 265 , 0 , 1536 , 6 , 17218 , 17219 , 16707 , 3855
DATA 17219 , 16707 , 1542 , 0 , 13569 , 265 , 257 , 309 , 0 , 1536
DATA 6 , 3906 , 3855 , 16655 , 3855 , 3855 , 17217 , 1603 , 0 , 2304
DATA 2357 , 257 , 309 , 0 , 0 , 1536 , 17217 , 3855 , 3855 , 3906
DATA 3855 , 3907 , 66 , 0 , 256 , 13577 , 265 , 309 , 0 , 1536
DATA 16705 , 16961 , 3855 , 3855 , 3906 , 3907 , 17167 , 66 , 0 , 0
DATA 2305 , 2313 , 2313 , 0 , 16902 , 16963 , 16962 , 17219 , 3907 , 16911
DATA 3855 , 16963 , 1601 , 0 , 0 , 256 , 265 , 13569 , 0 , 16705
DATA 16646 , 16705 , 16962 , 17218 , 3906 , 16961 , 16962 , 16706 , 6 , 0
DATA 0 , 257 , 2305 , 1536 , 65 , 0 , 16902 , 16705 , 17218 , 16705
DATA 16961 , 17219 , 17219 , 1601 , 0 , 0 , 257 , 2305 , 1536 , 6
DATA 0 , 1536 , 1601 , 16962 , 16646 , 16707 , 1542 , 16646 , 16707 , 0
DATA 256 , 0 , 265 , 1536 , 6 , 0 , 0 , 16646 , 16646 , 17217
DATA 1601 , 0 , 0 , 16646 , 0 , 0 , 0 , 9 , 1536 , 65
DATA 0 , 0 , 16896 , 1542 , 16646 , 6 , 0 , 0 , 1536 , 0
DATA 1 , 0 , 1 , 1536 , 1602 , 0 , 0 , 16640 , 16902 , 1542
DATA 0 , 0 , 0 , 1536 , 0 , 1 , 0 , 0 , 1536 , 16706
DATA 0 , 0 , 16646 , 16705 , 1601 , 0 , 0 , 0 , 1542 , 0
DATA 1 , 0 , 0 , 1536 , 17217 , 1602 , 1542 , 16705 , 17217 , 1601
DATA 6 , 0 , 1536 , 16646 , 6 , 1 , 0 , 0 , 1536 , 16902
DATA 17167 , 16962 , 16706 , 16963 , 16963 , 1601 , 1542 , 1542 , 1602 , 6
DATA 257 , 0 , 0 , 1536 , 16646 , 1601 , 16705 , 16962 , 66 , 16962
DATA 17219 , 3907 , 17167 , 1601 , 0 , 256 , 257 , 0 , 0 , 1601
DATA 1542 , 1542 , 16961 , 6 , 17158 , 16705 , 16962 , 16706 , 1542 , 0
DATA 256 , 2313 , 0 , 0 , 16640 , 16706 , 1542 , 16961 , 0 , 17152
DATA 1542 , 1542 , 1542 , 65 , 0 , 0 , 13569 , 0 , 0 , 0
DATA 0 , 1601 , 16961 , 0 , 16896 , 1601 , 16646 , 16706 , 0 , 0
DATA 0 , 256 , 0 , 0 , 0 , 0 , 1542 , 16962 , 16646 , 16902
DATA 1602 , 1601 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 6 , 1536 , 16961 , 16705 , 16961 , 1601 , 6 , 1536 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 6 , 1536 , 16705 , 16962 , 16706
DATA 1601 , 6 , 1536 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 65 , 1536 , 1542 , 1542 , 1542 , 1542 , 6 , 1536 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 1601 , 1536 , 1602 , 1601 , 1601
DATA 1601 , 65 , 16640 , 6 , 0 , 0 , 0 , 0 , 0 , 0
DATA 16902 , 1536 , 1542 , 1603 , 1603 , 1602 , 6 , 16646 , 1542 , 0
DATA 0 , 0 , 0 , 0 , 0 , 16896 , 16646 , 1542 , 1542 , 1542
DATA 16646 , 6 , 1542 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 1536 , 1602 , 16706 , 16655 , 16655 , 16706 , 1536 , 6 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0 , 16705 , 1542 , 1602 , 1602
DATA 6 , 1542 , 0 , 0 , 0 , 0 , 256 , 0 , 0 , 0
DATA 0 , 16902 , 1601 , 0 , 6 , 16646 , 1542 , 0 , 0 , 0
DATA 0 , 256 , 1 , 0 , 0 , 0 , 16640 , 17218 , 17167 , 16963
DATA 16705 , 6 , 0 , 0 , 0 , 0 , 256 , 265 , 0 , 0
DATA 0 , 1536 , 16961 , 17219 , 16706 , 6 , 0 , 0 , 0 , 0
DATA 0 , 256 , 2357 , 1 , 0 , 0 , 0 , 1542 , 16705 , 6
DATA 0 , 0 , 0 , 0 , 0 , 0 , 0 , 13621 , 257 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 0 , 0 , 13621 , 265 , 1 , 0 , 0 , 0 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
DATA 0 , 0 , 0 , 0 , 0 , 0
Mengenal Format Gambar Quick Basic
Format Gambar Quick Basic dipetakan ke dalam sekumpulan bilangan integer. File-file gambar dapat dijadikan satu di dalam program utama atau kita letakkan di dalam file eksternal yang dapat dipanggil. Berikut ini adalah contoh perintah untuk membaca file teks dari program QuickBasic:
OPEN “box.shp” FOR INPUT AS #1
DIM SHARED box(95): FOR i = 0 TO 95: INPUT #1, box(i): NEXT: CLOSE #1
Misalnya kita telah membuat file box.shp yang berisi sekumpulan bilangan integer untuk gambar kita, maka dapat kita buka dengan perintah OPEN untuk selanjutnya kita gunakan looping untuk membaca data-data gambar kita.
Palette
Jika anda perhatikan seorang pelukis yang hendak melukis. Terkadang, dia mencampurkan beberapa cat sehingga menjadi variasi warna yang bermacam-macam. Kira-kira gambaran seperti ini jugalah yang dikenal dalam Palette Komputer Grafik. Dengan Sistem Palette, kita dapat menghasilkan variasi warna yang tidak monoton.
Ini adalah penggalan program untuk menyimpan palette
Saving:
DIM pal&(255)
DEF SEG = VARSEG(pal&(0))
FOR col% = 0 to 255
OUT &h3c7, col%
POKE VARPTR(pal&(col%)), INP(&h3c9)
POKE VARPTR(pal&(col%)) + 1, INP(&h3c9)
POKE VARPTR(pal&(col%)) + 2, INP(&h3c9)
NEXT
BSAVE “FileName.pal”, VARPTR(pal&(0)), 1023
sedangkan berikut ini adalah penggalan program untuk memanggil sistem palette yang sudah disimpan
Loading:
DIM pal&(255)
DEF SEG = VARSEG(pal&(0))
BLOAD “FileName.pal”, VARPTR(pal&(0))
FOR col% = 0 to 255
OUT &h3c8, col%
OUT &h3c9, PEEK VARPTR(pal&(col%))
OUT &h3c9, PEEK VARPTR(pal&(col%)) + 1
OUT &h3c9, PEEK VARPTR(pal&(col%)) + 2
NEXT
Sistem Palette akan menyimpan warna RGB (Red, Green, Blue), dimana masing-masing dapat menyimpan nilai 0 sampai dengan 255.
Perintah diatas langsung mengakses hardware port (perintah OUT) sehingga menghasilkan kecepatan yang 100x lebih cepat dibandingkan perintah PALETTE dari QuickBasic sendiri.
Struktur File Bitmap .BMP 256 Color
File Gambar ada bermacam-macam. Yang paling sering digunakan adalah JPEG, karena sistem kompresinya sehingga menghasilkan gambar yang bagus dengan ukuran yang sangat kecil. Dalam kesempatan ini kita akan mempelajari struktur file BMP 256 warna yang sangat sederhana, karena tidak dikompresi. Secara umum struktur file .BMP adalah sebagai berikut:
54 Bytes awal digunakan untuk menyimpan Header File BMP
1024 Bytes berikutnya digunakan untuk menyimpan informasi palette, yang disusun BGR (Blue, Green, Red)
Sisa Bytes berikutnya adalah informasi gambar
Berikut adalah program untuk menampilkan file .BMP 256 warna
TYPE BMPHeaderType
id AS STRING * 2 ‘Should be “BM”
size AS LONG ‘Size of the data
rr1 AS INTEGER ‘
rr2 AS INTEGER ‘
offset AS LONG ‘Position of start of pixel data
horz AS LONG ‘
wid AS LONG ‘Image width
hei AS LONG ‘Image height
planes AS INTEGER ‘
bpp AS INTEGER ‘Should read 8 for a 256 colour image
pakbyte AS LONG ‘
imagebytes AS LONG ‘Width*Height
xres AS LONG ‘
yres AS LONG ‘
colch AS LONG ‘
ic AS LONG ‘
pal AS STRING * 1024 ‘Stored as
END TYPE
DIM BmpHeader AS BMPHeaderType
OPEN “marlex.bmp” FOR BINARY AS #1
GET #1, , BmpHeader
SCREEN 13 ‘ Set graphics mode
a$ = BmpHeader.pal ‘ Pal is stored in a 1024 character string
OUT &H3C8, 0 ‘ Start writing from Colour 0
FOR I% = 1 TO 1024 STEP 4
b% = ASC(MID$(a$, I%, 1)) \ 4 ‘blue
g% = ASC(MID$(a$, I% + 1, 1)) \ 4 ‘green
r% = ASC(MID$(a$, I% + 2, 1)) \ 4 ‘red
‘ I% + 3 is set to zero.
OUT &H3C9, r% ‘ Set the colour.
OUT &H3C9, g%
OUT &H3C9, b%
NEXT
DIM pixel AS STRING * 1 ‘ Our pixel “byte”.
iHeight% = BmpHeader.hei – 1 ‘ Subtract 1 for actual screen position
iWidth% = BmpHeader.wid – 1 ‘
‘Check Bytes
Byte.Remind = BmpHeader.imagebytes – (BmpHeader.wid * BmpHeader.hei)
IF Byte.Remind > 0 THEN
‘This will applied if there is unused bytes
‘we have to make modification on image width
iWidth% = iWidth% + (Byte.Remind / BmpHeader.hei)
END IF
key$ = INPUT$(1)
FOR y% = iHeight% TO 0 STEP -1 ‘ Countdown for upsidedown image
FOR x% = 0 TO iWidth%
GET #1, , pixel ‘ read pixel ‘ Read one pixel (byte)
PSET (x%, y%), ASC(pixel) ‘ Pixel is actually a string so we get the pixel
‘ number by requesting the “ASC” value
NEXT x%, y%
CLOSE #1
Kita dapat melewatkan 54 bytes pertama yang digunakan untuk menyimpan informasi header. 1024 bytes selanjutnya digunakan untuk menyimpan informasi palette. Yang menarik adalah informasi palette disusun terbalik menurut aturan BGR (Blue Green Red) yang biasanya kita mengenal RGB (Red, Green, Blue). Dan byte-byte selanjutnya adalah informasi gambar yang disusun dari bawah ke atas, jadi kalau kita perhatikan jika membuka file .BMP adalah dari bawah ke atas. Beberapa file bitmap .BMP mengabaikan beberapa byte yang ada di dalam filenya, sehingga penggunaan program LoadBmp terkadang tidak akan menghasilkan gambar yang diharapkan.
Contoh: kita akan mencoba membaca informasi header dari file .BMP
TYPE BMPHeaderType
ID AS STRING * 2 ‘Should be “BM”
size AS LONG ‘Size of the data
rr1 AS INTEGER ‘
rr2 AS INTEGER ‘
Offset AS LONG ‘Position of start of pixel data
horz AS LONG ‘
wid AS LONG ‘Image width
hei AS LONG ‘Image height
Planes AS INTEGER ‘
bpp AS INTEGER ‘Should read 8 for a 256 colour image
pakbyte AS LONG ‘
imagebytes AS LONG ‘Width*Height
xres AS LONG ‘
yres AS LONG ‘
colch AS LONG ‘
ic AS LONG ‘
pal AS STRING * 1024 ‘Stored as
END TYPE
DIM BmpHeader AS BMPHeaderType
filename$ = “marlex.bmp”
OPEN filename$ FOR BINARY AS #1
GET #1, , BmpHeader
COLOR 15, 0
SCREEN 0
CLS
PRINT “File .BMP Information”
PRINT “Filename : “, filename$
PRINT “BMP ID : “, BmpHeader.ID
PRINT “Size in bytes : “, BmpHeader.size
PRINT “RR1 : “, BmpHeader.rr1
PRINT “RR2 : “, BmpHeader.rr2
PRINT “Horz : “, BmpHeader.horz
PRINT “Start Offset : “, BmpHeader.Offset
PRINT “Total Planes : “, BmpHeader.Planes
PRINT “BitPerPlanes : “, BmpHeader.bpp
PRINT “X-Res : “, BmpHeader.xres
PRINT “Y-Res : “, BmpHeader.yres
PRINT “Width : “, BmpHeader.wid
PRINT “Height : “, BmpHeader.hei
PRINT “Image Bytes : “, BmpHeader.imagebytes
PRINT “Pak Bytes : “, BmpHeader.pakbyte
PRINT “Colch : “, BmpHeader.colch
PRINT “IC : “, BmpHeader.ic
key$ = INPUT$(1)
Outputnya adalah sbb:
Filename : marlex.bmp
BMP ID : BM
Size in bytes : 1590
RR1 : 0
RR2 : 0
Horz : 40
Start Offset : 1078
Total Planes : 1
BitPerPlanes : 8
X-Res : 0
Y-Res : 0
Width : 15
Height : 32
Image Bytes : 512
Pak Bytes : 0
Colch : 0
IC : 0
Jika kita lihat ukuran file bmpnya adalah 1590 bytes , sedangkan ukuran imagenya sendiri adalah 512 bytes. Kalau kita jumlahkan, 54 +1024+512 = 1590 bytes!!! Ini artinya semua byte yang ada di dalam file digunakan untuk menampilkan gambar. (http://www.wahyukurniawan.info)

0 komentar:

Posting Komentar

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More