Hoşgeldiniz: OyunYapimi.org
 
Ara
Konular
  Üye Olun!    
Ana Menü
 Ana Sayfa
 Anketler
 Dosyalar
 Dökümanlar
 Forum
 Haber Arşivi
 WWW Linkleri
 Üye Listesi

Forumlar
Forumlarda Arama
 
[ Ara ]
Son yazilanlar

free ebooks - 2004-05-16 14:47 free ebooks...
oyun yazmak için - 2004-05-15 11:13 oyun yazmak için...
Sinus dalgası - 2004-05-14 19:21 Sinus dalgası...
Demosu yakında... - 2004-05-06 15:11 Demosu yakında......
Depth Test - 2004-05-03 20:55 Depth Test...
forum mesajlarini duzenlemek - 2004-05-03 19:34 forum mesajlarini ...
Başka Programlara Erişmek - 2004-05-03 17:44 Başka Programlara ...
Güzel bir e-book bağlantısı.. - 2004-05-03 16:06 Güzel bir e-book b...
Okyanus Dalgasi - 2004-05-03 16:00 Okyanus Dalgasi...
3d Shoot em up - 2004-05-03 15:57 3d Shoot em up...
Esnek Güç - 2004-05-03 13:32 Esnek Güç...
UltimateGameProgramming.com - 2004-05-03 12:29 UltimateGameProgra...
Function Pointer Nedir ne ise yarar - 2004-05-03 01:35 Function Pointer N...


Konu Disi


LAMER - 2004-05-10 01:58 LAMER...
anasafa yok forum var - 2004-05-08 16:01 anasafa yok forum ...
Anasayfa Kapali  Fakat.. - 2004-05-06 15:05 Anasayfa Kapali F...
Texture Arşivi - 2004-05-03 01:39 Texture Arşivi...
Yeni Kitap: Elektronik Hobi - 2004-05-03 00:29 Yeni Kitap: Elektr...
3DTURK - 2004-05-02 23:27 3DTURK...
Online Oyun - 2004-05-02 19:27 Online Oyun...


Splatt Forum

BMP Kütük Formatı ve Kullanımı

(1561 kelime)
(449 okuma)   Yazdırılabilir Sayfa




BMP Kütük Formatı

Bu dökümanda Windows BMP (bitmap) resim formatını inceleyeceğiz. Dökümanı okuduktan sonra kolaylıkla .bmp uzantılı resim kütüklerini yükleyen ve kullanan programlar yazabileceksiniz. Gerekli olan yerlerde örnek kod parçacıkları ile anlatılan kavramların C/C++ kullanılarak gerçekleştirimlerini de açıklamaya çalışacağım.

BMP Formatı Hakkında:

Bitmap (BMP) resim formatı Microsoft ve IBM işbirliği ile oluşturulmuş oldukça basit bir formattır. Windows işletim sisteminde bu format standart olarak desteklenmekte, resim, ikon ve pointer grafiklerini saklamak için kullanılmaktadır. Bu resim formatının kısaca özelliklerini sıralamak gerekirse:

  • Windows ve OS/2 işletim sistemlerince desteklenir.
  • INTEL platformuna bağımlı özellikler içerir.
  • 1,4,8,16,24 ve 32 bit lik renk çözünürlüklerine destek verir.
  • 16 bitten düşük renk çözünürlükleri için palet yapıları kullanılır.
  • Pixel verileri sıkıştırılmamış (genel kullanım) veya sıkıştırılmış olarak saklanılabilir.
  • Sıkıştırma kullanılıyor ise RLE algoritması olarak adlandırılan ve resim verisi üzerinde kayıp olmasını engelleyen bir algoritma türü kullanılır.

Bu resim formatının bazı avantaj ve dezavantajları bulunmakta. İsterseniz bunlarıda liste halinde görelim:

Avantajları:

  • Kullanımı kolay, kütük yapısı anlaşılır (okuyan ve yazan programlar geliştirmek oldukça basit.).
  • Sıkıştırma algoritması resimde kayba yol açmıyor. (Örnegin JPEG formatı sıkıştırma oranınca kayba uğratır.)

Dezavantajları:

  • Çok yer kaplıyor. (sıkıştırma kullanan türevi bile...)
  • INTEL platformuna bağımlı.
  • Saydamlık verisi renk bilgisi içeriğinde yok (ALPHA kanalı bulunmuyor)

BMP Kütüklerinin Yapısı:

Aşağıdaki tabloda BMP kütükleri içerisinde yer alan veri bloklarının kütük başlangıç adresleri (offset), uzunlukları, isimleri ve kısa açıklamaları verilmiştir. Uzunluklar byte cinsinden, offset değerleri ise 16'lık sistemde (hexadecimal), ve BMP kütüğünün başına görelidir. Byte ordering şekli INTEL platformuna göredir. (Little Endian). Örneğin 32 bitlik bir sayıyı (4 byte) gösterirken kütükten okunan ilk bayt sayının en düşük öncelikli byte değeri (0-7 nci bitler), okunan 4.byte ise en yüksek öncelikli byte değeridir.

offset uzunluk (byte) alan ismi kısa açıklama
0000h 2 identifier kütüğün bitmap kütüğü oldugunu belirten imza. BM karakterlerini içerecek şekildedir. (0x42 , 0x4D)
0002h 4 file size bmp kütüğünün uzunluğunu taşır.
0006h 4 reserved kullanılmamakta
000Ah 4 bitmap data offset resim pixel verisi bloğunun kütük içerisindeki başlangıç adresini içerir.
000Eh 4 bitmap header size bitmap info header isimli veri bloğunun uzunluğu bilgisini içerir. Bu alan windows bmp formatı için herzaman 0x28 değerini taşır.
0012h 4 horizontal width resmin pixel olarak yatay genişliği
0016h 4 vertical height resmin pixel olarak düşey yüksekliği
001Ah 2 number of planes 0x01 değerini içermeli
001Ch 2 bits per pixel (bpp) resimdeki her pixel için kaç bitlik renk verisi kullanıldığını belirtir. Resmin desteklediği renk derinliği için farklı aşağıdaki değerleri alabilir:
1: 2 renk
2: 4 renk
4: 16 renk
8: 256 renk
16: 216 renk
24: 224 renk
32: 232 renk
001Eh 4 compression method kullanılan sıkıştırma algoritmasını belirtir. Aşağıda belirtilen değerleri alabilir:
00: sıkıştırma yok
01: RLE-8 bit
02: RLE-4 bit
03: Bitfields
0022h 4 bitmap data length resim verisinin uzunluğunu içerir. Uzunluk 4 ün katlarını alacak şekilde gerekirse yuvarlanır.
0026h 4 horizontal resolution resmin genişliğini pixel/metre olarak verir
002Ah 4 vertical resolution resmin yüksekliğini pixel/metre olarak verir
002Eh 4 colors resim içinde kullanılan renk sayısını içerir. 256 renklik resimlerde 0x100 değerini içerir, 24-32 bitlik resimlerde 0x00 değerini içermektedir.
0032h 4 important colors önemsiz.
0036h N x 4 palette resim palet verisini içerir. Palet verisi kullanan resimler için gereklidir (16,24,32 bitlerde kullanilmaz). 4 byte lik bloklardan olusur. 1.byte mavi (blue), 2.byte yesil (green) 3.byte kirmizi (red) 4. byte ise 0x00 olrak doldurulur. N degeri 2,4,16,256 degerlerini (renk sayisi kadar..) alabilir.
0436h kütük sonuna kadar... bitmap data resim verisi bu blokta bulunur. 16 bitlik resimler de her pixel için 2 byte kullanilir. ilk 5 bit blue, sonraki 5 bit green, sonraki 5 bit red renk verisi içerir. son bit kullanilmaz. 24 bitlik resimlerde her renk komponenti 1 byte ile ifade edilir. 32 bitlik resimlerde yine her renk komponenti 1 byte ile ifade edilir ama bu sefer her pixel için 3 degil 4 byte kullanılır. Son byte her zaman 0x00 değerini içerir. Resim verisi asağıdan yukarıya doğru çıkan satırlardan oluşur. Yani okunan ilk değer resmin sol alt köşesinin renk verisidir. Okunan son değer ise resmin sağ üst köşesi renk verisini içerir.

BMP Kütüklerini Okumak:

Şimdi yukarıda verilen kütük yapısındaki bilgileri kullanarak .bmp kütüklerini okuyan bir C programı yazacağız. Programın basit olması açısından sadece sıkıştırılmamış ve 24 bitlik renk verisi içeren kütükleri okuyabileceğiz.

İlk olarak aşağıdaki yapıları tanımlayalım:

struct sBitmapHeader {
   unsigned short id;
   unsigned int   fileSize;
   unsigned int   reserved;
   unsigned int   dataOffset;
   unsigned int   BmpInfoHeaderSize;
   unsigned int   width;
   unsigned int   height;
   unsigned short planes;
   unsigned short bpp;
   unsigned int   compMethod;
   unsigned int   dataLength;
   unsigned int   horzRes;
   unsigned int   vertRes;
   unsigned int   numColors;
   unsigned int   numImportantColors;
};

struct sPixel {
   unsigned char b;
   unsigned char g;
   unsigned char r;
};

Bu yapıları tanımladıktan sonra artık programımızın bitmap yükleme kısımlarını içeren rutinleri yazmaya başlayabiliriz. İlk olarak diskte yer alan "ornek.bmp" isimli kütüğü açan ve bitmap başlik verisini (header) okuyan kod parçasını yazalım:

struct sBitmapHeader header;
FILE   *fp;
// kütüğü aç
fp = fopen("ornek.bmp","rb");
if (!fp) {
   printf("kütük bulunamadı!");
   exit(-1);
}

// header verisini oku
fread(&header,sizeof(header),1,fp);

Yukaridaki birkaç satırlık kod ile bitmap başlık verisini (header) okuduk. header olarak tanımladığımız değişkenin ilgili alanlarına erişerek bmp kütüğü hakkında birçok yararlı bilgiye ulaşabiliriz. Bizim için en önemli bilgiler width (genislik), height (yükseklik) ve bpp (bits per pixel) isimli alanlardır. Aşağıdaki kod ile öncelikle bmp kütüğünün bizim istediğimiz formatta veri içerip içermediğine bakılıyor, daha sonra ise kütükte yer alan pixel verileri belleğe okunuyor.

// kütüğün Windows BITMAP kütüğü olup olmadığını doğrula
if (header.id != 0x4D42) {
   printf("kütük windows bitmap (bmp) kütügü degil!");
   exit(-1);
}

// renk derinliği 24 bit olmalı
if (header.bpp != 24) {
   printf("kütük renk derinliği 24 bit değil!");
   exit(-1);
}

// sıkıştırılma kullanılmamıs olması gerekiyor
if (header.compMethod != 0) {
   printf("kütük sıkıştırılmış veri içeriyor!");
   exit(-1);
}

// pixel veri bloğunun başlangıcına gidelim
fseek(fp,header.dataOffset,SEEK_SET);

// tüm pixel verilerini alacak büyüklükte bir bellek alani olusturup
// daha sonra diskten bu alana pixel verilerini okuyoruz
sPixel *data = new sPixel[header.width * header.height]; 
fread(data,sizeof(sPixel),header.width*header.height,fp);
// artik kütük ile isimiz bitti
fclose(fp);

Evet işte bu kadar basit. Artık elimizde data dizisi içerisinde resmi oluşturan her pixelin renk değerleri bulunuyor. Bu değerlere örneğin data[i].r, data[i].g, data[i].b şeklinde erişebilirsiniz. Değiştirdiğiniz değerleri daha sonra tekrar kütüğe yazabilirsiniz.

OpenGL İle Birlikte Kullanımı:

Son olarak bu resim verisini OpenGL programlarında texture olarak kullanmak istiyorsanız aşağıdaki örnek kod parçacığını kullanmanız yeterlidir.

// OpenGL r,g,b şeklinde dizilim ister. Bizdeki ise b,g,r şeklinde
// Bu ufak rutin ile çevirim işlemi yapıyoruz.
for (int i=0;i<header.width*header.height;++i) {
   unsigned char tmp = data[i].r;
   data[i].r = data[i].b;
   data[i].b = tmp;
}
int textureId;
glGenTextures(1,&textureId);
glBindTexture(GL_TEXTURE_2D,textureId);

glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

gluBuild2DMipmaps(GL_TEXTURE_2D,3,header.width,header.height,GL_RGB,GL_UNSIGNED_BYTE,data);

Herzaman olduğu gibi bu döküman hakkındaki fikirlerinizi, varsa hataları ve düzeltme isteklerinizi sitemiz forumları aracılığı ile veya deniz@oyunyapimi.org adresi üzerinden direk olarak benimle bağlantıya geçerek bildirebilirsiniz.

M.Deniz Aydınoğlu :: 2003 :: www.oyunyapimi.org
  

[ Geri Dön: Oyun Yapımı (Genel) | Dökümanlar İndeksi ]





Web site Engine's code is Copyright © 2002 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.