首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

BMP 圖片格式深度解析:文件結構、數據讀取與顏色分離完整指南

     編輯:關於VC++

BMP 文件四大區塊結構

  1. 文件頭 (BITMAPFILEHEADER):類型、大小、數據偏移
  2. 資訊頭 (BITMAPINFOHEADER):寬高、位深、壓縮、解析度、調色板資訊
  3. 調色板 (RGBQUAD 陣列):索引色對應的 RGB 值
  4. 像素數據區:掃描行按 4 字節對齊補齊

關鍵結構體定義


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。

各位深度讀取與顏色分離代碼

1 位 (單色)


for (int y=0; y=0; k--)
      color[y][x+k] = (val>>k) & 1; // 0/1 索引調色板
  }

4 位 (16 色)


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;
  }

8 位 (256 色)


int pitch = (w+3)&~3;
idx = buf[y*pitch + x]; // 直接為調色板索引
r = pal[idx].rgbRed; g = pal[idx].rgbGreen; b = pal[idx].rgbBlue;

16 位 (高彩色)

行寬 pitch = w + w%2 (2 字節對齊)。兩種格式由 biCompression 決定:

  • BI_RGB (555):R:5 G:5 B:5,最高位保留
  • BI_BITFIELDS:數據前有 3 個 DWORD 掩碼,依掩碼判斷 555/565

// 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;

24 位 (真彩色)


int pitch = (w*3 + 3) & ~3;
ofs = y*pitch + x*3;
b = buf[ofs]; g = buf[ofs+1]; r = buf[ofs+2]; // BGR 順序

32 位 (真彩色+Alpha)

無需對齊,每像素 4 字節。


ofs = (y*w + x)*4;
b = buf[ofs]; g = buf[ofs+1]; r = buf[ofs+2]; // 第 4 字節常為保留/Alpha

實作提示

  • 完整解析器見附帶工程 OnDraw() 中代碼
  • 執行程式後直接拖入 BMP 檔即可查看解析結果
  • 注意 biHeight 正負決定掃描行順序(自下而上/自上而下)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved