# 如何理解BMP圖片格式
## 一、BMP格式概述
BMP(Bitmap)是Windows操作系統中的標準圖像文件格式,最早由微軟公司于1990年代推出。作為**無損位圖格式**的代表,它以簡單的數據結構和廣泛的兼容性著稱。BMP文件直接存儲每個像素的顏色信息,不進行壓縮(默認情況下),這使得它在圖像處理領域具有獨特優勢。
### 核心特點
- **無壓縮特性**:原始BMP格式通常不壓縮(支持可選RLE壓縮)
- **顏色深度靈活**:支持1位(黑白)到32位(ARGB)多種模式
- **設備無關性**:DIB(設備無關位圖)結構保證跨平臺顯示一致性
## 二、文件結構解析
BMP文件由四個邏輯部分組成,其二進制結構如下圖所示:
┌─────────────────┐ │ 文件頭(14字節) │ ├─────────────────┤ │ 信息頭(40字節+) │ ├─────────────────┤ │ 調色板(可選) │ ├─────────────────┤ │ 像素數據 │ └─────────────────┘
### 1. 文件頭(BITMAPFILEHEADER)
```c
typedef struct {
UINT16 bfType; // 固定為"BM"(0x4D42)
UINT32 bfSize; // 文件總字節數
UINT16 bfReserved1; // 保留字段
UINT16 bfReserved2; // 保留字段
UINT32 bfOffBits; // 像素數據偏移量
} __attribute__((packed)) BMPFileHeader;
typedef struct {
UINT32 biSize; // 本結構體大?。ㄍǔ?0字節)
INT32 biWidth; // 圖像寬度(像素)
INT32 biHeight; // 圖像高度(正數表示倒序存儲)
UINT16 biPlanes; // 必須為1
UINT16 biBitCount; // 每像素位數(1/4/8/16/24/32)
UINT32 biCompression; // 壓縮方式(0表示無壓縮)
UINT32 biSizeImage; // 像素數據大?。ㄗ止潱? // ...其他字段省略
} BMPInfoHeader;
以24位真彩色BMP為例:
計算行字節數:
row_size = (width * 3 + 3) & ~3 # 每行補0對齊到4字節
像素訪問公式:
// 獲取(x,y)處像素(假設height為正數)
pixel_offset = bfOffBits + (height - y - 1) * row_size + x * 3;
blue = data[pixel_offset];
green = data[pixel_offset + 1];
red = data[pixel_offset + 2];
特性 | BMP | PNG | JPEG |
---|---|---|---|
無損壓縮 | ?(原始) | ? | ? |
透明度支持 | 32位版本支持 | ? | ? |
編輯友好度 | 極高 | 高 | 低 |
graph LR
A[標準BMP] --> B[Alpha通道BMP]
A --> C[CMYK模式BMP]
A --> D[設備相關位圖DDB]
bfType
是否為”BM”import struct
def read_bmp(filename):
with open(filename, 'rb') as f:
# 讀取文件頭
header = f.read(14)
_, size, _, _, offset = struct.unpack('<2sIHHI', header)
# 讀取信息頭
info = f.read(40)
width, height = struct.unpack('<ii', info[4:12])
# 讀取像素數據...
盡管BMP格式在存儲效率上不占優勢,但其結構透明性和解碼簡便性使其在特定領域仍不可替代。理解BMP格式有助于深入掌握數字圖像的基礎存儲原理,為處理更復雜的圖像格式奠定基礎。在需要精確控制每個像素的場景下,BMP依然是值得考慮的格式選擇。 “`
注:本文實際約1100字,完整版可擴展以下內容: 1. 不同位深度的具體存儲差異 2. RLE壓縮算法的詳細說明 3. 與DIB/DDB的關聯關系 4. 更多編程語言實現示例
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。