------------------------------------------------------------------------------------
Bitmap resim doyası genel olarak üç bölümden oluşur, bunlar;
1- Bitmap File Header (Dosya başlığı)
2- Bitmap Info Header (Resim bilgi başlığı)
3- Color map (Renk haritası)
Resime Ayrılan Veri Alanı:
29x29 pixel ve 256 renk bilgisine sahip bir resim için şu hesap yapılmaktadır.Öncelikle resmin satır genişliği hesaplanır. Yani bir satır için ne kadar veri alanı gerektiği tespit edilir. 256 renk bilgisi COLORMAP denilen alanda saklanır ve bu tip resim dosyaları 8 bit olarak bilinmektedir.
Bu hesap için aşağıdaki fonksiyon kullanılabilir.
Kod: Tümünü seç
Private Funtion GetRowSize(ByVal nWidth As Integer, ByVal nBitCount As Integer) As Long
GetRowSize = 4 * (((nBitCount / 8) * nWidth + 3) \ 4)
End FunctionVeriAlanı = GetRowSize(29,
Bitmap File Header:
Bitmap file header yapısı aşağıdaki gibidir (14 byte boyutunda).
Kod: Tümünü seç
Private Type BITMAPFILEHEADER
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End TypebfType: 'B' ve 'M' harfleri olan 19778 degerini geri döndürür. (Bitmap dosya tipi için)
bfSize: Dosya boyutu (byte cinsinden)
bfReserved1: Boş
bfReserved2: Boş
bfOffBits: Bitmap file header'ın bittiği, Bitmap info header'ın başladığı değeri işaret eder
Örnek:
Herhangi bir bilgisayarın C: kök sürücünde ;
256 renk biti ile örneklenmiş ve 160x120 pixel boyutlarındaki bir dosyayının incelenmesi;
Kod: Tümünü seç
Private Const FileName As String = "C:\test.bmp"
Dim bfh As BITMAPFILEHEADER
'VB 6.0 da Standart open yöntemi ile dosyayı açınız.
Open FileName For Binary Access Read As #1
' Get komutu ile 14 byte uzunluğundaki BITMAPFILEHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bfh
' ve son olarak dosyayı kapatınız.
Close #1Kod: Tümünü seç
' BITMAPFILEHEADER içindeki bilgileri Debug penceresine yazdırınız.
Debug.Print "bfType: " & bfh.bfType
Debug.Print "bfSize: " & bfh.bfSize
Debug.Print "bfReserved1: " & bfh.bfReserved1
Debug.Print "bfReserved2: " & bfh.bfReserved2
Debug.Print "bfOffBits: " & bfh.bfOffBitsbfType: 19778
bfSize: 20278
bfReserved1: 0
bfReserved2: 0
bfOffBits: 1078
Kısaca sonucu açıklarsak;
* bfType: 19778 değerini döndürdü, yani dosya bitmap (BM) tipindedir.B harfinin Asci kodu 66, M hafinin ise 77 dir. Basit bir hesapla bu değerlerin integer karşılığı "bfType = 'M' * 256 + 'B'" yani "bfType = 77 * 256 + 66" dir.
* bfSize: 20278 değerini döndürdü, yani bu değeri kendimiz hesaplarsak.
bfSize = Len(BITMAPFILEHEADER) + Len(BITMAPINFOHEADER) + Len(COLORMAP) + Len(IMAGESIZE)
şeklindedir.
Bu hesap sırasında bahsetmediğimiz COLORMAP ve BITMAPINFOHEADER bilgileri var.İlerleyen konularda bu bilgiler verilecektir. Neticede COLORMAP hesabı şu şekilde yapılır.Yukarıdaki örnekte tanımdladığımız (Dim bfh As BITMAPFILEHEADER) bfh kullanılarak;
Len(COLORMAP) = bfh.bfOffBits - Len(bfh) - Len(BITMAPINFOHEADER) = 1078 - 14 - 40 = 1024 byte olacaktır.
Sonuç olarak bfSize değeri;
bfSize = 14 + 40 + 1024 + GetRowSize(160,
bfSize = 14 + 40 + 1024 + 160 * 120 = 20278
GetRowSize(160,
bfSize = 29 * 29 * (BitCount /
Fakat asıl değer;
bfSize = GetRowSize(Width, BitCount) * Height
bfSize = GetRowSize(29, 24) * 29 = 2552 olacaktır.
Çıkan sonuç daima 4'e tam olarak bölünmektedir. (4 byte değerinde RGB ve Alpha)
* bfOffBits: 1078 değerini döndürdü.
Yani
bfOffBits = Len(BITMAPFILEHEADER) + Len(BITMAPINFOHEADER) + Len(COLORMAP)
bfOffBits = 14 + 40 + (256 * 4) (256 renk değeri için)
Bitmap Info Header
Bitmap Info Header 40 byte lık bir alan kaplar. Yığın yapısı aşağıdaki gibidir.
Kod: Tümünü seç
Private Type BITMAPINFOHEADER
biSize As Long ' Size of info header
biWidth As Long ' Width of image
biHeight As Long ' Height of image
biPlanes As Integer ' Number of color planes
biBitCount As Integer ' Number of bits per pixel
biCompression As Long ' Type of compression to use
biSizeImage As Long ' Size of image data
biXPelsPerMeter As Long ' X pixels per meter
biYPelsPerMeter As Long ' Y pixels per meter
biClrUsed As Long ' Number of colors used
biClrImportant As Long ' Number of important colors
End Type* biWidth: Resmin genişliği (pixel cinsinden)
* biHeight: Resmin yüksekliği (pixel cinsinden)
* biPlanes: Renk planı (genellikle 1 dir)
* biBitCount: 1 pixel için ayrılan veri alanı (1, 4, 8, 16, 24, 32 gibi)
* biCompression: Resim bilgisinin sıkıştırılmış veya sıkıştırılmamış olduğu bilgisi.
Genel olarak biCompression değeri
BI_RGB = 0, BI_RLE8 = 1, BI_RLE4 = 2, BI_BITFIELDS = 3 geğerlerinden biri olur.
Tabi burada anlatılmayan farklı sıkıştırma tekniklerinden biri de olabilir. Fakat
şu an sadece bu değerleri size aktaracağım.
BI_RGB: Resimde herhangi bir sıkıştırma olmadığı bilgisidir. Resim verisi olduğu
saklanır.
BI_RLE8: 8 bit uzunluk hesabına göre sıkıştırma
BI_RLE4: 4 bit uzunluk hesabına göre sıkıştırma
BI_BITFIELDS: RGB resim bilgisinin RGB maskeleme bilgisiyle sıkıştırıldığı vs...
* biSizeImage: Resim için ayrılan veri alanı değeridir. Bu değer yukarıda anlatılan
biSizeImage = GetRowSize(Width, BitCount) * Height sonucuna göre hesaplanır.
* biXPelsPerMeter: Metre başına pixel genişliği
* biYPelsPerMeter: Metre başına pixel yüksekliği
* biClrUsed: Sayı renklerin kullanıldığı
* biClrImportant: Sayı önemli renkleri
Yukarıdaki kodu yeni bilgilerle tekrar düzenlersek;
Kod: Tümünü seç
Option Explicit
'Colormap entry structure
Private Type RGBQUAD
rgbBlue As Byte ' Blue value
rgbGreen As Byte ' Green value
rgbRed As Byte ' Red value
rgbReserved As Byte ' Reserved
End Type
'BMP file header structure
Private Type BITMAPFILEHEADER
bfType As Integer ' Magic number for file
' bfType As String * 2 ' Magic number for file (veya kullanılabilir)
bfSize As Long ' Size of file
bfReserved1 As Integer ' Reserved
bfReserved2 As Integer ' ...
bfOffBits As Long ' Offset to bitmap data
End Type
'BMP file info structure
Private Type BITMAPINFOHEADER
biSize As Long ' Size of info header
biWidth As Long ' Width of image
biHeight As Long ' Height of image
biPlanes As Integer ' Number of color planes
biBitCount As Integer ' Number of bits per pixel
biCompression As Long ' Type of compression to use
biSizeImage As Long ' Size of image data
biXPelsPerMeter As Long ' X pixels per meter
biYPelsPerMeter As Long ' Y pixels per meter
biClrUsed As Long ' Number of colors used
biClrImportant As Long ' Number of important colors
End Type
'Bitmap information structure
Private Type BITMAPINFO_24
bmiHeader As BITMAPINFOHEADER ' Image header
bmiColors() As RGBQUAD ' Image colormap
End Type
Private Const FileName As String = "C:\test.bmp"
Private Sub Form_Load()
Dim bfh As BITMAPFILEHEADER
Dim bih As BITMAPINFOHEADER
'VB 6.0 da Standart open yöntemi ile dosyayı açıyoruz.
Open FileName For Binary Access Read As #1
' Get komutu ile 14 byte uzunluğundaki BITMAPFILEHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bfh
' Get komutu ile 40 byte uzunluğundaki BITMAPINFOHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bih
' ve son olarak dosyayı kapatıyoruz.
Close #1
With bih
Debug.Print "biSize: " & .biSize
Debug.Print "biWidth: " & .biWidth
Debug.Print "biHeight: " & .biHeight
Debug.Print "biPlanes: " & .biPlanes
Debug.Print "biBitCount: " & .biBitCount
Debug.Print "biCompression: " & .biCompression
Debug.Print "biSizeImage: " & .biSizeImage
Debug.Print "biXPelsPerMeter: " & .biXPelsPerMeter
Debug.Print "biYPelsPerMeter: " & .biYPelsPerMeter
Debug.Print "biClrUsed: " & .biClrUsed
Debug.Print "biClrImportant: " & .biClrImportant
End With
End SubbiSize: 40
biWidth: 160
biHeight: 120
biPlanes: 1
biBitCount: 8
biCompression: 0
biSizeImage: 19200
biXPelsPerMeter: 2835
biYPelsPerMeter: 2835
biClrUsed: 0
biClrImportant: 0
Color Map
Kod: Tümünü seç
Private Sub Form_Load()
Dim bfh As BITMAPFILEHEADER
Dim bih As BITMAPINFOHEADER
Dim cmAry() As RGBQUAD
Dim nColorSize As Long
'VB 6.0 da Standart open yöntemi ile dosyayı açıyoruz.
Open FileName For Binary Access Read As #1
' Get komutu ile 14 byte uzunluğundaki BITMAPFILEHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bfh
' Get komutu ile 40 byte uzunluğundaki BITMAPINFOHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bih
' Color map alanı nedir?
nColorSize = (bfh.bfOffBits - Len(bfh) - Len(bih)) / 4 ' 4 = Len(RGBQUAD)
If nColorSize > 0 Then
Redim cmAry(nColorSize - 1)
' Renk haritasını dosyadan alıyoruz.
Get #1, ,cmAry
End If
' ve son olarak dosyayı kapatıyoruz.
Close #1
End SubRenk haritası yukarıdaki bilgilerden anlaşıldığı gibi RGBA (Red, Green, Blue, Alpha) bilgilerini içerir. Yani bir pixel için 4 byte'lık alan barındırır. Yukarıdaki örnekte kullanılan dosya içindeki her bir pixel alanının renk haritası kullanılmadan 4 byte'lık bir alan kaplaması gerekmektedir. Renk haritası kullanılarak, renk geçişleri
hassasiyetinden ödün verilmiş, fakat dosya boyutları azaltılmıştır.Aynı dosya boyutunu (20278 bytes uzunluğundaki) renk haritası kullanmadan hesaplarsak;
Kod: Tümünü seç
FileSize = GetRowSize(Width, BitCount) * Height + Len(BITMAPFILEHEADER) + Len(BITMAPINFOHEADER)
FileSize = GetRowSize(160, 32) * 120 + 14 + 40
FileSize = 76854 byteResim Bilgisi
Bitmap File Header, Bitmap Info Header ve ColorMap bilgileri dosyadan alındıktan sonra kalan bilgi resim verisinin bilgisidir.Buna göre yukarıdaki kodu tekrar düzenlersek;
Kod: Tümünü seç
Private Sub Form_Load()
Dim bfh As BITMAPFILEHEADER
Dim bih As BITMAPINFOHEADER
Dim cmAry() As RGBQUAD
Dim nColorSize As Long
Dim imgDatas() As Byte
'VB 6.0 da Standart open yöntemi ile dosyayı açıyoruz.
Open FileName For Binary Access Read As #1
' Get komutu ile 14 byte uzunluğundaki BITMAPFILEHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bfh
' Get komutu ile 40 byte uzunluğundaki BITMAPINFOHEADER bilgisini
'... değişkenimize aktarıyoruz.
Get #1, ,bih
' Color map alanı nedir?
nColorSize = (bfh.bfOffBits - Len(bfh) - Len(bih)) / 4 ' 4 = Len(RGBQUAD)
If nColorSize > 0 Then
Redim cmAry(nColorSize - 1)
' Renk haritasını dosyadan alıyoruz.
Get #1, ,cmAry
End If
' Resim bilgisini alıyoruz
Redim imgDatas(bih.biSizeImage - 1)
Get #1, , imgDatas
' ve son olarak dosyayı kapatıyoruz.
Close #1
End SubBu makalenin hazırlanmasının iki amacı var:
1.Herhangi bir resim dosyasının arka planına virüs kodları yerleştirilebilir.
2.Resim dosyalarının kodlarının açıklanmasıdır.
Herkese İyi Günler
TRWE_2012
Düzce_Akçakoca
:oops: :)

