鑑於最近
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)