Programming Practice

這個程式作業是有關影像處理。一個點陣圖 (bitmap image) 的檔案格式可分為檔頭 (file header) 和影像資料 (image information) 兩部份,其定義如下列的結構:

typedef struct BitmapHeader {

  // 檔頭部份
  char Type[2]; // 兩個固定字元 "BM"
  unsigned Size; // 檔案長度
  char Reserved[4]; // 保留欄位
  unsigned OffsetBits; // 像素資料起始位置的位移量

  // 資料部份
  unsigned InfoSize; // 資料區域大小
  unsigned Width; // 影像寬度
  unsigned Height; // 影像高度
  short unsigned Planes; // 顯示裝置平面數,其值通常為 1
  short unsigned BitPerPixel; // 像素位元數
  unsigned Compression; // 壓縮資料
  unsigned ImageSize; // 影像區域大小
  unsigned XResolution; // 水平解析度,每公尺多少像素
  unsigned YResolution; // 垂直解析度,每公尺多少像素
  unsigned Colors; // 色彩種類
  unsigned ImportantColors; // 重要顏色
} Header;

檔頭及影像資料結束後,繼續為一個色盤區域 (palette),其大小為 OffsetBits-InfoSize-14 個位元組;其後即為像素區域,大小佔用 ImageSize 個位元組,此二區域的資料型態可宣告為 unsigned char 的指標。在本習作題目,不需要用到色盤區域。像素區域的儲存方式如下:

  1. 像素的儲存是以列為主,自左而右,自下而上。即最後一列儲存在像素區域的最前面。

  2. 每個像素佔用三個位元組代表紅、綠、藍 (RGB) 各佔一個位元組,其順序為藍色 (B)、綠色 (G)、然後紅色 (R)。

  3. 每一列的位元組數必須是 4 的倍數。如果每列實際像素的總位元組不是 4 的倍數,則在結尾填入 0 的資料。

寫一個 C 語言的程式以執行下列步驟:

  1. 讀入一個彩色影像點陣圖檔案,

  2. 讀入三個變數值,firstFilterbandwidthweight. 變數 firstFilter 的值在 0 3 之間,是開始的濾光鏡選項,0 為灰階、1 為藍色濾光鏡、2 為綠色濾光鏡、3 為紅色濾光鏡;bandwidth 的值在 0 與影像寬度 header.width 之間,是某一個濾光鏡效果水平方向的色素寬度;weight 的值在 0255 之間,是濾光效果的比重,0 為無濾光效果,255 為全色濾光鏡。灰階轉換公式為 "imageData[k] = (imageData[k] * weight * 20 + imageData[k+1] * weight * 50 + imageData[k+2] * weight * 30) / (weight * 100); imageData[k+1] = imageData[k]; imageData[k+2] = imageData[k];";藍色濾光鏡公式為 "imageData[k] = imageData[k]<255-weight ? imageData[k]+weight : weight;";綠色濾光鏡公式為 "imageData[k+1] = imageData[k+1]<255-weight ? imageData[k+1]+weight : weight;";紅色濾光鏡公式為 "imageData[k+2] = imageData[k+2]<255-weight ? imageData[k+2]+weight : weight;"。

  3. 將影像以水平方向每隔  bandwidth 像素從 firstFilter 開始輪流做灰階或藍、綠、紅濾光鏡效果的轉換,

  4. 將濾光鏡效果轉換後的影像檔案檔頭和資料部份的內容到顯示器上。

在主程式中使用 argcargv 兩個參數 (請參考 http://www.acm.uiuc.edu/webmonkeys/book/c_guide/1.3.html1.3.2 節) 以便主程式啟動時可接受一或兩個外來參數。第一個外來參數是彩色影像的檔名,第二個外來參數為轉換後濾光鏡效果轉換影像的檔名。如果濾光鏡效果轉換影像的檔名從缺時,其預設檔名為 "banded_filter.bmp"。 你可使用下列彩色影像 blue_hills.bmp, water_lilies.bmp, sunset.bmp,abraham_lake.bmp, red_dragon.bmp, 和 wildflowers.bmp 作為測試,也可使用你自己準備的影像。如果你的影像檔不是 .bmp 的點陣圖檔,請用繪圖工具將其轉成點陣圖的檔案。

以下為程式執行結果範例:

>color_filter abraham_lake.bmp color_filter.bmp


Select the starting filter (0: gray-level, 1: blue, 2: green, 3: red): 3

Enter the bandwidth (between 0 and 800): 200

Enter the filter weight(between 0 and 255): 200


The color-filtered image is "color-filter.bmp".

Type: BM
Size: 1080054
Resserved:


OffsetBits: 54
InfoSize: 40
Width: 800
Height: 450
Planes: 1
BitPerPixel: 24
Compression: 0
ImageSize: 1080000
XResolution: 5669
YResolution: 5669
Colors: 0
ImportantColors: 0

以下為彩色影像圖例:

以下為濾光效果轉換後的影像 (firstFilter=3, bandwidth=200, weight=200) 圖例:

濾光效果轉換後的影像 (firstFilter=3, bandwidth=100, weight=50) 圖例: