鑑於最近
Altera_installer_rev2
莫名其妙都不會動,實在太@#$@#$
只好再把以前的技倆搬出來,用ftp多線程下載(altera: 哭哭)
ftp://ftp.altera.com/outgoing/release/
裡面有所有版本的Altera軟體
2010年11月9日 星期二
C語言讀寫BMP影像檔
[Introduction]
撰寫視窗軟體時應該是沒有如此的煩惱,因為bcb, vc++都有提供視覺化元件可以使用,但是對於開發演算法以及產生test pattern時根本不需要圖形化介面,或者是嵌入式系統在開發時需要使用semihosting輸出影像時,這時要開圖檔或者寫圖檔都是件麻煩事。而bmp是一個最簡單的泛用圖檔格式,但是又不須像raw一樣,需要設定長寬大小,只要點兩下馬上看得到結果。對於嵌入式系統或者vlsi相關的設計,有很大的幫助。因此這邊簡單寫一個讀寫bmp的函式。
[Article]
BMP檔案格式,由bmpheader與image array兩個部份組成。
bmp header通常長度為58byte,所以也可以值些忽略前面的部份,讀取影像的資料,但是為了寫回電腦時還是一樣是bmp檔,所以還是需要把header記下來,先宣告一個結構(struct)來存放header資料,
讀完header後,取出width與height,由於一個pixel有rgb三個pixel,算影像大小的公式為width*height*3,再與(filesize-bitmap_dataoffset)比較看看是否相等,判斷大小是否有算錯,
下面是讀取bmp的函式
但是要注意一點,BMP擺放影像是上下顛倒所以要記得將影像轉回來,不然存出來的圖會是顛倒的。
撰寫視窗軟體時應該是沒有如此的煩惱,因為bcb, vc++都有提供視覺化元件可以使用,但是對於開發演算法以及產生test pattern時根本不需要圖形化介面,或者是嵌入式系統在開發時需要使用semihosting輸出影像時,這時要開圖檔或者寫圖檔都是件麻煩事。而bmp是一個最簡單的泛用圖檔格式,但是又不須像raw一樣,需要設定長寬大小,只要點兩下馬上看得到結果。對於嵌入式系統或者vlsi相關的設計,有很大的幫助。因此這邊簡單寫一個讀寫bmp的函式。
[Article]
BMP檔案格式,由bmpheader與image array兩個部份組成。
bmp header通常長度為58byte,所以也可以值些忽略前面的部份,讀取影像的資料,但是為了寫回電腦時還是一樣是bmp檔,所以還是需要把header記下來,先宣告一個結構(struct)來存放header資料,
typedef struct _lbheader{
unsigned short identifier; // 0x0000
unsigned int filesize; // 0x0002
unsigned int reserved; // 0x0006
unsigned int bitmap_dataoffset; // 0x000A
unsigned int bitmap_headersize; // 0x000E
unsigned int width; // 0x0012
unsigned int height; // 0x0016
unsigned short planes; // 0x001A
unsigned short bits_perpixel; // 0x001C
unsigned int compression; // 0x001E
unsigned int bitmap_datasize; // 0x0022
unsigned int hresolution; // 0x0026
unsigned int vresolution; // 0x002A
unsigned int usedcolors; // 0x002E
unsigned int importantcolors; // 0x0032
unsigned int palette; // 0x0036
} __attribute__((packed,aligned(1))) lbheader;
記住gcc有資料格式對齊的考量,為了到時後讀檔方便,所以加入__attribute__((packed,aligned(1))),強制gcc把結構作緊密排列,這樣是為了到時候讀取資料時可以直接使用指標來擺放資料,就不需要一筆一筆去指定資料。lbheader hbmp; unsigned char* ptr; ptr = (unsigned char *)&hbmp; fread(ptr, sizeof(unsigned char), sizeof(lbheader), fp);像這樣開始讀取檔案的58byte,直接使用unsigned char型態指標從結構開始位址開始寫入,數值就會按照位置擺入結構中。
讀完header後,取出width與height,由於一個pixel有rgb三個pixel,算影像大小的公式為width*height*3,再與(filesize-bitmap_dataoffset)比較看看是否相等,判斷大小是否有算錯,
下面是讀取bmp的函式
int readbmp(char* filename, lbheader& hbmp, int mode, unsigned char* buffer)
{
FILE* ifp;
char c[128];
unsigned char* ptr;
sprintf(c, "./result/%s.bmp", filename);
ifp = fopen(c, "rb");
if(ifp==NULL){
printf("readbmp: file open error\n");
return -1;
}
ptr = (unsigned char *)&hbmp;
fread(ptr, sizeof(unsigned char), sizeof(lbheader), ifp);
if(mode==1){
fread(buffer, sizeof(unsigned char), (hbmp.width*hbmp.height*3), ifp);
}
else{
fclose(ifp);
return (hbmp.width*hbmp.height*3);
}
fclose(ifp);
return 1;
}
要讀取影像時要先知道影像大小,以便宣告足夠的記憶體空間,所以要呼叫兩次readbmp(),一次先取到header,第二次才真的取影像資料,// 先宣告指標與結構
unsigned char* bimage;
lbheader bmpinfo;
// 取得適當大小的陣列
bimage = (unsigned char *)malloc(sizeof(unsigned char)*readbmp("2", bmpinfo, 0, bimage));
// 讀取影像
readbmp("2", bmpinfo, 1, bimage);
寫入bmp的function。int writebmp(char* filename, lbheader hbmp, unsigned char* buffer)
{
FILE* ofp;
char c[128];
unsigned char* ptr;
sprintf(c, "./result/%s.bmp", filename);
ofp = fopen(c, "wb");
if(ofp==NULL){
printf("writebmp: file open error\n");
return -1;
}
ptr = (unsigned char *)&hbmp;
fwrite(ptr, sizeof(unsigned char), sizeof(lbheader), ofp);
fwrite(buffer, sizeof(unsigned char), (hbmp.width*hbmp.height*3), ofp);
fclose(ofp);
return 1;
}
但是要注意一點,BMP擺放影像是上下顛倒所以要記得將影像轉回來,不然存出來的圖會是顛倒的。
訂閱:
意見 (Atom)