Re: [問題] C語言讀BMP圖檔後顯示資訊

看板C_and_CPP (C/C++)作者 (simple life)時間16年前 (2009/06/16 21:16), 編輯推噓4(4015)
留言19則, 4人參與, 最新討論串2/3 (看更多)
影像的width跟height是藏在header陣列中 索引值18~25的地方 如 weight的資料記錄在 header[18]~header[21] height的資料則記在 header[22]~height[25] 如果要讀取 可參考下列code long width = (long)header[18] + ((long)header[19] << 8) + ((long)header[20] << 16) + ((long)header[21] << 24); long height = (long)header[22] + ((long)header[23] << 8) + ((long)header[24] << 16) + ((long)header[25] << 24); 其中 << 為位元運算子,做什麼用應該不用說明了吧! 其他BM size 你可以去網路上找一下資料 看header裡面都放了什麼東西 之後再按格式取出並正確的組合 就可以讀取你想要的資料了 ※ 引述《SiriusJinn (假斯汀)》之銘言: : 以下是讀檔的程式碼 : #include <stdio.h> : #include <stdlib.h> : #include <windows.h> : int bmp_read(unsigned char *image, int xsize, int ysize, char *filename) : { : FILE *fp; : char fname_bmp[128]; : long i, j; : unsigned char *image_buf; : unsigned char header[54]; : image_buf = (unsigned char *)malloc((size_t)xsize*ysize*3); : if (image_buf == NULL) return -1; : sprintf(fname_bmp, "%s.bmp", filename); : if ((fp = fopen(fname_bmp, "rb")) == NULL) return -1; : fread(header, sizeof(unsigned char), 54, fp); : fread(image_buf, sizeof(unsigned char), (size_t)(long)xsize*ysize*3, fp); : fclose(fp); : for (i = 0; i < ysize; i++){ : for (j = 0; j < xsize; j++){ : *(image + xsize*(ysize-i-1) + j) : = *(image_buf + 3*(xsize*i +j) +2); : *(image + xsize*(ysize-i-1) + j + xsize*ysize) : = *(image_buf + 3*(xsize*i +j) +1); : *(image + xsize*(ysize-i-1) + j + xsize*ysize*2) : = *(image_buf + 3*(xsize*i +j) ); : } : } : free(image_buf); : return 0; : } : int main() : { : unsigned char *image; : int xsize = 512; : int ysize = 512; : image = (unsigned char *)malloc((size_t)xsize * ysize * 3); : if (image == NULL) : return -1; : bmp_read(image, xsize, ysize, "lena.bmp"); : free(image); : } : 想請問如果我想把一些資料如 BM size width height 輸出在螢幕的話 : printf該怎麼寫呢?我read的部份有把 file-header 跟 information-header : 存進來了嗎? : 綠色部份的作用是什麼,可否幫解釋一下! : 感謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.118.7.163

06/16 21:18, , 1F
好像回錯問題了XD
06/16 21:18, 1F

06/16 21:34, , 2F
可以用 *( (long*) (&header[18]) ) 嗎....@_@"
06/16 21:34, 2F

06/16 21:34, , 3F
啊, 這樣在大印弟安感覺好像會有問題....Orz
06/16 21:34, 3F

06/16 21:52, , 4F
06/16 21:52, 4F

06/16 22:30, , 5F
感謝!
06/16 22:30, 5F

06/16 23:23, , 6F
printf("image width:%d\n", (int)width);其實才是問題解答
06/16 23:23, 6F

06/16 23:28, , 7F
回VT:不行。hader紀錄順序是低位至高位。 舉個例說明
06/16 23:28, 7F

06/16 23:31, , 8F
若十進制數字為12345678好了,header儲存此數字的順序為
06/16 23:31, 8F

06/16 23:32, , 9F
header[18]=78 header[19]=56 header[20]=34 header[21]=12
06/16 23:32, 9F

06/16 23:34, , 10F
以上只是舉例說明,實際上是二進制才對。
06/16 23:34, 10F

06/16 23:50, , 11F
假設用0x12345678, header[18]=0x78, header[19]=0x56,
06/16 23:50, 11F

06/16 23:51, , 12F
以此類推的話, 在一般常見的小印弟安系統(如windows),
06/16 23:51, 12F

06/16 23:51, , 13F
不就用*( (long*) (&header[18]) )剛剛好嗎?? 而且我記
06/16 23:51, 13F

06/16 23:52, , 14F
得也有直接寫struct(alignment 1)直接read 54 bytes回
06/16 23:52, 14F

06/16 23:52, , 15F
來直接就對應好所有data member的呀@_@"
06/16 23:52, 15F

06/17 00:10, , 16F
什麼小印弟安啊... 我不認識這個人啊
06/17 00:10, 16F

06/17 00:13, , 17F
little endian, 因為endian老不會拼, 所以總叫印弟安:)
06/17 00:13, 17F

06/17 00:21, , 18F
剛看了一下,好像跟CPU硬體設計有關.且compile時要下參數
06/17 00:21, 18F

06/17 00:22, , 19F
很麻煩內....而且我覺得程式不好看(←這才是重點)
06/17 00:22, 19F
文章代碼(AID): #1ADvj1pz (C_and_CPP)
文章代碼(AID): #1ADvj1pz (C_and_CPP)