看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《pigcat1315 (還是朋友?)》之銘言: : 問題(Question): : 24位元的bmp : 因為我用fstream 來寫開讀檔 跟大家用file = =a 不太一樣 : 所以標頭讀完後 = 口= 我就不知道也怎讀取rgb了 我以為,你會讀 bmp header 後,應該也會讀 rgb 了... : int open_file() : { : bmpfileheader fhd; : bmpinfoheader ihd; : RGB color; : fstream file ; //宣告fstream物件 : file.clear(); : file.open("3.bmp",ios::in|ios::binary ); : // file head 的部分都省略 : //以上info的讀取也省略 : file.read((char*)&ihd.bmpColorImportant,4); 我其實很好奇一點:你是不是沒用過 PSPad / UltraEditor 去看 hex mode ? 00000000h: A4 6B B0 A8 A5 D5 A4 63 A4 66 A6 43 0D 0A A4 53 ; xxxxxxxxxxxx..又 00000010h: AD 6E A4 40 AD D3 A4 48 B9 4C B1 A1 A4 48 B8 60 ; 要一個人過情人節 00000020h: 2C 20 47 47 ; , GG 這段你看得出有什麼關聯性嗎?如果會看的話,我建議先用上述其中一個先去觀查, 會比較有感覺。 以下只做 拋磚引玉 之效 (說白了,就是沒什麼神奇的技巧在裡面) ----- 在讀 bmp 時,若堅持要用 iofstream object,我其實比較建議用 ifstream, 下面做一些簡單的轉換 (聲明,這只是在「功能上」有相似,但整體運作概念不同), 變數 fp、fin 都是一直延用 ----- 1. 開啟檔案 /* in c */ FILE *fp = fopen("1.bmp", "rb"); if(fp==NULL) { printf("open fail.\n"); exit(1); } /* in c++ */ ifstream fin("1.bmp", iso::in | iso::binary); if(!fin) { cout << "open fail.\n"; exit(1); } ----- 2. 讀單一字元 /* in c */ char ch = fgetc(); /* in c++ */ char ch = fin.get(); ----- 3. 讀一個 block 這裡,假設要直接讀此 bmp filesize, 是從 02h 開始,佔 4 bytes unsigned file_size; /* in c */ fseek(fp, 0x02, SEEK_SET); // start position, want to set fread(&file_size, sizeof(byte), 4); // fread(&file_size, sizeof(unsigned), 1); // "maybe" worst. /* in c++ */ fin.seekg(0x02); fin.read((char*)&file_size, 4); ---- 4. 關檔 /* in c */ fclose(fp); /* eof 將被自動清除 */ /* in c++ */ fin.close(); fin.clear(); /* 清除所有 flag, 含 eof */ ---- 基本上讀 bmp 用上面幾個轉換就可以。至於你說要讀 rgb 的話,可以, 下面程式碼沒試過,推斷應可類似這麼做 typedef struct tagRGB{ byte B; byte G; byte R; byte reserve; }RGB; /* 給 buffer 大小 */ RGB **raw_data = new RGB*[height]; for(size_t i=0; i!=height; ++i) raw_data[i] = new RGB[width]; /* 開始讀 RGB */ fin.seekg(0x36); /* start from 0x36(54)*/ for(size_t i=0; i!=height; ++i) /* 把第 i */ fin.read((char*)raw_data[i], width*3); 這裡是先假設你已從 header 讀出 width、heigh 之做法, 每次都一列一列讀進來, fin.read( (char*)raw_data[i], /* 將第 i 列之 raw_data 讀入 */ width*3 /* 每一列有 width 個 pixel, 一個 pixel 有 bgr,3bytes */ ); 這裡會有更好的做法,但若對 陣列轉換 (一維 <----> 二維) 沒很熟的話, 就暫用這方法吧。 ------------ 你看到一些很莫名的 code, 那是因為 bmp 存檔之後,可能一些軟體「不小心」又多塞了一些 garbge 進去, 也因為這些 garbge ,會使得 bmp header information 變得不可靠。如 實際 filelength 與 bmp information filelength 不合; 還有一些「對齊」問題 (有些要對,有些不用對【應說是必對】); 若單純寫 24bits bmp,這不難; 要寫完「完整的 bmp」,要真正完整,就把 spec K 完 (我知道很無聊,所以沒 K ); 要快速交差,直接研究別人的 code (當然是要挑過), 看他們到底處理了哪些問題。 結束前提醒一件事,是可以用 fin.get() 一個一個慢慢讀, 但如果整份 rgb raw_data 都用 fin.get() 這.. 效能有待加強。 fin.seekg / fin.read 部份建議再開一份 test project 去摸熟, 大部份都在摸這二隻函式,其它的 domain know how... 我不想代 K Spec XD ------------ 以上,供參閱。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41 ※ 編輯: tropical72 來自: 180.177.78.41 (08/05 20:18)
pigcat1315:感謝大大整理QQ 08/05 21:07
angleevil:你的例子有怨念.不過謝謝你.因為我也不會rgb 08/05 21:25