首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言 BMP 8位灰度圖灰度縮減 16 倍:調色板 RGB 三通道數值必須相等才能保持灰度

     編輯:程式設計綜合問答

問題現象

將 8 位灰度圖 (0-255) 縮減至 16 級 (0-15),調色板從 256 色縮為 16 色,RGB 數值範圍改為 0.0-1.0。處理後圖片**出現彩色噪點,不再是純灰度**。

根因:調色板 RGB 三通道數值不一致

灰度圖核心特徵:**R = G = B**。你的代碼:


double gray = i * 0.0667; // 0.0 ~ 1.0
(map + i)->rgbBlue = gray;
(map + i)->rgbRed = gray;
(map + i)->rgbGreen = gray; // 三通道賦相同值 → 正確

**但結構體定義用 `double` 儲存 RGB**,而 BMP 標準調色板 `RGBQUAD` 每通道 **1 字節 (0-255, `BYTE`)**。寫入檔案時若直接寫 `double` (8 字節) 會導致:

  1. 調色板區塊膨脹 8 倍,檔案頭 `bfOffBits` / `biClrUsed` 不匹配。
  2. 讀取端按 `BYTE` 讀取,只取了 `double` 低位字節 → 數值亂碼 → R/G/B 不等 → 出現顏色。

修正方案

  1. 調色板結構體改用 `BYTE` (或 `unsigned char`)**:
    
    typedef struct tagRGBQUAD {
        BYTE rgbBlue;
        BYTE rgbGreen;
        BYTE rgbRed;
        BYTE rgbReserved;
    } RGBQUAD;
    
  2. 灰度映射 0-15 → 0-255**:
    
    BYTE gray = (BYTE)(i * 255.0 / 15.0); // 0, 17, 34, ... 255
    (map + i)->rgbBlue = gray;
    (map + i)->rgbGreen = gray;
    (map + i)->rgbRed = gray;
    (map + i)->rgbReserved = 0;
    
  3. 像素資料映射**:`pixel = pixel / 16` (0-15) 正確,但寫入檔案時仍是 0-15,**讀取端會按 0-255 解讀**,顯示極暗。需**擴展回 0-255**:

// 讀取原像素 0-255
BYTE orig = src->imageData[...];
// 量化為 0-15
BYTE quantized = orig >> 4; // 等價 /16
// **擴展回 0-255 存入目標**
dst->imageData[...] = quantized * 17; // 0, 17, 34... 255

關鍵點總結

  • **BMP 調色板 = `RGBQUAD` 陣列,每項 4 字節 (B,G,R,保留),值域 0-255**。
  • **灰度 = R=G=B**,任何一方不等即產生色彩。
  • **量化後必須擴展回 0-255** 存入像素資料,否則圖片極暗(0-15 視為 0-255 顯示)。
  • 結構體對齊:`#pragma pack(1)` 確保 `RGBQUAD` 無填充字節。

總結

灰度圖處理變彩色 = **調色板結構體型別錯誤 (`double` vs `BYTE`)** 導致寫入/讀取不匹配,或 **量化後未擴展回 0-255**。修正結構體、保持 R=G=B、像素值擴展回標準範圍,圖片即恢復純灰度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved