看板 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()
{
}
--#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
回列表(←)
分享