BITMAPFILEHEADER):類型、大小、數據偏移BITMAPINFOHEADER):寬高、位深、壓縮、解析度、調色板資訊RGBQUAD 陣列):索引色對應的 RGB 值
typedef struct tagBITMAPFILEHEADER {
WORD bfType; // 必須為 'BM'
DWORD bfSize; // 文件總大小
WORD bfReserved1; // 0
WORD bfReserved2; // 0
DWORD bfOffBits; // 像素數據偏移量
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize; // 結構大小 (40)
LONG biWidth; // 寬(像素)
LONG biHeight; // 高(像素),正值=底部優先
WORD biPlanes; // 必須為 1
WORD biBitCount; // 1/4/8/16/24/32
DWORD biCompression; // 0=BI_RGB, 1=RLE8, 2=RLE4, 3=BITFIELDS
DWORD biSizeImage; // 圖像大小(可為0)
LONG biXPelsPerMeter; // 水平解析度
LONG biYPelsPerMeter; // 垂直解析度
DWORD biClrUsed; // 實際使用調色板數
DWORD biClrImportant; // 重要顏色數
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD {
BYTE rgbBlue, rgbGreen, rgbRed, rgbReserved;
} RGBQUAD;
**每掃描行必須 4 字節對齊**,不足補零。實際行寬 pitch = (width * bitCount / 8 + 3) & ~3。
for (int y=0; y=0; k--)
color[y][x+k] = (val>>k) & 1; // 0/1 索引調色板
}
int pitch = (w+1)/2; pitch = (pitch+3)&~3; // 實際行寬
for (int y=0; y> 4) : (buf[y*pitch + x/2] & 0x0F);
r = pal[idx].rgbRed; g = pal[idx].rgbGreen; b = pal[idx].rgbBlue;
}
int pitch = (w+3)&~3;
idx = buf[y*pitch + x]; // 直接為調色板索引
r = pal[idx].rgbRed; g = pal[idx].rgbGreen; b = pal[idx].rgbBlue;
行寬 pitch = w + w%2 (2 字節對齊)。兩種格式由 biCompression 決定:
R:5 G:5 B:5,最高位保留
// 555 格式
b = (buf[ofs] & 0x1F);
g = (((buf[ofs+1]<<6)&0xFF)>>3) + (buf[ofs]>>5);
r = (buf[ofs+1]<<1)>>3;
// 565 格式 (掩碼紅=0xF800)
b = (buf[ofs] & 0x1F);
g = (((buf[ofs+1]<<5)&0xFF)>>2) + (buf[ofs]>>5);
r = buf[ofs+1]>>3;
int pitch = (w*3 + 3) & ~3;
ofs = y*pitch + x*3;
b = buf[ofs]; g = buf[ofs+1]; r = buf[ofs+2]; // BGR 順序
無需對齊,每像素 4 字節。
ofs = (y*w + x)*4;
b = buf[ofs]; g = buf[ofs+1]; r = buf[ofs+2]; // 第 4 字節常為保留/Alpha
OnDraw() 中代碼biHeight 正負決定掃描行順序(自下而上/自上而下)