顯示廣告
隱藏 ✕
看板 Knuckles
作者 Knuckles(阿德)
標題 為了找工作的C++課程--作業5
時間 2008年08月27日 Wed. AM 02:34:57


看完第10章

這章少講到一個特殊的資料型別 union
有興趣的可以點這個 http://caterpillar.onlyfun.net/Gossip/CGossip/union.html 看看

接著看
http://caterpillar.onlyfun.net/Gossip/CGossip/UnFormatFileIO.html 
http://caterpillar.onlyfun.net/Gossip/CGossip/BinaryFileIO.html 
學一下C語言的檔案存取


接著就要來寫個比較複雜的東西,也就是這一階段的期末作業:

「存取BMP檔案」

關於BMP的檔案格式請參考: http://knuckles.twbbs.org/cppclass/05_Bitmap/bitmap.htm
裡面使用到的特殊型別名稱與結構名稱為Windows GDI中定義的
但我們不打算使用Windows GDI的函式庫,而是自行練習定義那些東西

首先在專案裡新增一個 bitmap.h 的檔,填入下面講的東西:

1.
	
使用10-1自訂資料型別的方法定義
	
BYTE 為 unsigned char (用來存 1 byte 的資料)
	
WORD 為 unsigned short (用來存 2 byte 的資料)
	
DWORD 為 unsigned long (用來存 4 byte 的資料)

2.
	
接著寫出上個作業第2題的那四個巨集函式:
	
RGB()、GetRValue()、GetGValue()、GetBValue()
	

3.
	
宣告那些在BMP中會用到的結構
	

	
BITMAPFILEHEADER、BITMAPINFOHEADER、RGBQUAD
	

	
另外再宣告一個自訂的結構:
	
typedef struct tagBITMAP{
	
  BITMAPFILEHEADER bmpFileHeader;
	
  BITMAPINFOHEADER bmpInfoHeader;
	
  RGBQUAD *pPalette;    // allocate memory
	
  BYTE    *pColorTable; // allocate memory
	
} BITMAP;

	
其中 Palette 與 ColorTable 因為不確定大小,要用動態記憶體配置
	
所以這邊使用指標來存
	

	
將這些結構的宣告用 #pragma pack(1) 與 #pragma pack() 包起來,像這樣:
	

	
#pragma pack(1) //結構成員對齊的界限設為 1 byte
	

	
// 宣告結構的地方
	

	
#pragma pack() // 取消自訂結構成員對齊的界限

4.
	
最後宣告我們要寫的函數

	
BITMAP * bmpCreate(long width, long height, WORD bpp); //產生一個自訂長寬的BITMAP結構
	
BITMAP * bmpLoad(const char *filename);                //載入一個BMP檔,並轉為一個BITMAP結構
	
int bmpSave(BITMAP *pBmp, const char *filename);       //將BITMAP結構存成BMP檔
	
int bmpClose(BITMAP *pBmp);                            //將BITMAP結構中產生的動態記憶體消除

	
int
	
  bmpGetWidth(BITMAP *pBmp);     //取得BITMAP結構中的寬值
	
int   bmpGetHeight(BITMAP *pBmp);    //取得BITMAP結構中的高值
	
DWORD bmpGetPixel(BITMAP *pBmp, int x, int y);               //取得(x,y)點的色彩值
	
int   bmpSetPixel(BITMAP *pBmp, int x, int y, DWORD color);  //設定(x,y)點的色彩值
	
BYTE  bmpGetGrayPixel(BITMAP *pBmp, int x, int y);             //取得(x,y)點的灰階值
	
int   bmpSetGrayPixel(BITMAP *pBmp, int x, int y, BYTE color); //設定(x,y)點的灰階值

bitmap.h檔填入以上的東西後,再新增一個bitmap.cpp檔
開頭先加上 #include "bitmap.h" 後
將上面第4步宣告的那些函數的定義寫出來

在主程式main.cpp中使用我們寫函式存取bmp檔
#include <iostream>
#include "bitmap.h"
using namespace std;

int main()
{
	
// 載入一張彩色的圖 lena.bmp
	
BITMAP * pBmp1 = bmpLoad("lena.bmp");
	
int width  = bmpGetWidth(pBmp1);
	
int height = bmpGetHeight(pBmp1);

	
// 產生一個大小與lena.bmp相同的圖
	
BITMAP * pBmp2 = bmpCreate(width,height,24);
	

	
// 將第一張圖的上下顛倒的結果放進第二張圖
	
DWORD color;
	
int x,y;
	
for(y=0;y<height;y++){
	
	
for(x=0;x<width;x++){
	
	
	
color = bmpGetPixel(pBmp1,x,y);
	
	
	
bmpSetPixel(pBmp2,x,height-y-1,color);
	
	
}
	
}
	

	
// 將第二張圖存檔成 lena2.bmp
	
bmpSave(pBmp2,"lena2.bmp");
	

	
// 最後記得要close
	
bmpClose(pBmp1);
	
bmpClose(pBmp2);

	
system("pause");
	
return 0;
}
--
※ 來源: 台大電信 DISP 實驗室 (http://disp.twbbs.org)
※ 作者: Knuckles  來自: 140.112.175.128  時間: 2008-08-27 02:34:57
※ 編輯: Knuckles  來自: 140.112.175.128  時間: 2008-08-27 02:40:03

參考解答:

bitmap.h
bitmap.cpp
main.cpp

(右鍵另存新檔)

※ 編輯: Knuckles  來自: 140.112.175.128  時間: 2008-10-19 02:11:27
※ 編輯: Knuckles  來自: 140.112.175.128  時間: 2008-10-19 02:12:55
※ 編輯: Knuckles  來自: 140.112.175.130  時間: 2009-05-31 15:26:39
※ 編輯: Knuckles  來自: 140.112.175.130  時間: 2009-08-03 00:08:25
※ 編輯: Knuckles  時間: 2010-10-23 04:42:54  來自: 111-248-0-184.dynamic.hinet.net
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 1405 
分享網址: 複製 已複製
iloveyouever 轉錄至看板 my_time_my_heart 時間:2010-08-03 21:02:26
terrykyo 轉錄至看板 terrykyo 時間:2011-04-04 01:51:42
TL 轉錄至看板 TL (使用複製) 時間:2012-12-08 19:46:37
e)編輯 d)刪除 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇