English Deutsch Français Italiano Español Português 繁體中文 Bahasa Indonesia Tiếng Việt ภาษาไทย
所有分類

幫我一行一行說明 感謝您

//-------------bmp_write-------------------------//
int bmp_write(unsigned char *image, int xsize, int ysize, char *filename)
{
long i, j;
FILE *fp;
long file_size, width, height;
unsigned char *image_buf;
char fname_bmp[128];
unsigned char header[54] = {0x42, 0x4d,0,0,0,0,0,0,0,0,
54,0,0,0,40,0,0,0,0,0,0,0,0,0,0,0,1,0,24,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0};
file_size = (long)xsize * (long)ysize * 3 + 54;
header[2] = (unsigned char)(file_size & 0x000000ff);
header[3] = (file_size >> 8) & 0x000000ff;
header[4] = (file_size >> 16) & 0x000000ff;
header[5] = (file_size >> 24) & 0x000000ff;
width = xsize;
header[18] = width & 0x000000ff;
header[19] = (file_size >> 8) & 0x000000ff;
header[20] = (file_size >> 16) & 0x000000ff;
header[21] = (file_size >> 24) & 0x000000ff;
height = ysize;
header[22] = height & 0x000000ff;
header[23] = (file_size >> 8) & 0x000000ff;
header[24] = (file_size >> 16) & 0x000000ff;
header[25] = (file_size >> 24) & 0x000000ff;

image_buf = (unsigned char *)malloc((size_t)xsize*ysize*3);
if (image_buf == NULL) return -1;

for (i = 0; i < ysize; i++){
for(j = 0; j *(image_buf + 3*(xsize*i + j))
= *(image + xsize*(ysize-i-1) + j + (long)xsize*ysize*2);
*(image_buf + 3*(xsize*i+j)+1)
=*(image+xsize*(ysize-i-1)+j+(long)xsize*ysize);
*(image_buf + 3*(xsize*i+j)+2)
= *(image +xsize*(ysize-i-1)+j);
}
}
sprintf(fname_bmp,\"b.bmp\",filename);
if ((fp=fopen(fname_bmp,\"wb\")) == NULL) return -1;
fwrite(header,sizeof(unsigned char),54,fp);
fwrite(image_buf,sizeof(unsigned char),(size_t)(long)xsize*ysize*3,fp);
fclose(fp);
free(image_buf);
return 0;
}

2006-02-15 18:36:12 · 2 個解答 · 發問者 低調人 1 in 電腦與網際網路 程式設計

2 個解答

//-------------bmp_write-------------------------//
/*image是指向來源數據的指標,xsize是新檔案的寬度,ysize是高度,filename是新檔案名稱*/
int bmp_write(unsigned char *image, int xsize, int ysize, char *filename)
{
long i, j; //迴圈用

FILE *fp; //檔案作業用指標

//紀錄檔案大小、寬,高 之用
long file_size, width, height;

//緩衝區用 指標
unsigned char *image_buf;

//用來存放新檔的檔名
char fname_bmp[128];

/**初始化 檔頭規劃區 資料**/
unsigned char header[54] = {0x42, 0x4d,0,0,0,0,0,0,0,0,
54,0,0,0,40,0,0,0,0,0,0,0,0,0,0,0,1,0,24,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0};
file_size = (long)xsize * (long)ysize * 3 + 54; //計算出檔案大小
//存入 "檔案大小" 到檔頭規劃區的 記錄位址
header[2] = (unsigned char)(file_size & 0x000000ff);
header[3] = (file_size >> 8) & 0x000000ff;
header[4] = (file_size >> 16) & 0x000000ff;
header[5] = (file_size >> 24) & 0x000000ff;
//存入 "寬" 到檔頭規劃區的 記錄位址
width = xsize;
header[18] = width & 0x000000ff;
header[19] = (file_size >> 8) & 0x000000ff;
header[20] = (file_size >> 16) & 0x000000ff;
header[21] = (file_size >> 24) & 0x000000ff;
//存入 "高" 到檔頭規劃區的 記錄位址
height = ysize;
header[22] = height & 0x000000ff;
header[23] = (file_size >> 8) & 0x000000ff;
header[24] = (file_size >> 16) & 0x000000ff;
header[25] = (file_size >> 24) & 0x000000ff;
/****************/

//配置 所需的緩衝記憶體大小
image_buf = (unsigned char *)malloc((size_t)xsize*ysize*3);
//根據上一句,如果 ysize或xsize 為零則,檔案有問題,程式離開
if (image_buf == NULL) return -1;

/* */
for (i = 0; i < ysize; i++){
for(j = 0; j /**將image指標所指的資料 複製 給image_buf指標所指的空間,藉以達成複製工作**/
*(image_buf + 3*(xsize*i+j)) = *(image + xsize*(ysize-i-1) +j+ (long)xsize*ysize*2);
*(image_buf + 3*(xsize*i+j) +1)= *(image + xsize*(ysize-i-1) +j+ (long)xsize*ysize);
*(image_buf + 3*(xsize*i+j) +2)= *(image + xsize*(ysize-i-1) +j);
//算法有點難解析,大概有簡單的縮放效果吧
}
}

//在fname_bmp上存入 filename+"b.bmp" 字串
sprintf(fname_bmp,"%s-b.bmp",filename); //這裡個人多加了個 %s-,否則filename將缺乏意義
/*
sprintf函式定義如下:
int sprintf (char * szBuffer, const char * szFormat, ...) ;
第一個參數是字元緩衝區;後面是一個格式字串。Sprintf不是將格式化結果標準輸出,而是將其存入szBuffer。
*/

//以二進位模式 開一新檔,如果有問題 程式離開
if ((fp=fopen(fname_bmp,"wb")) == NULL) return -1;

//寫入檔頭
fwrite(header,sizeof(unsigned char),54,fp);

//寫入緩衝區資料
fwrite(image_buf,sizeof(unsigned char),(size_t)(long)xsize*ysize*3,fp);

//關閉檔案
fclose(fp);

free(image_buf); //釋放緩衝區記憶體
return 0;
}

2006-02-16 10:52:40 補充:
header[3] = (file_size >> 8) & 0x000000ff;
意思是 file_size 除以2 八次 (也就除以 256)
再與 0x000000ff 作邏輯 AND 運算 (也就是限制在 255 這個內)

總之就是以 "倒序"的方式記錄數值罷了 (這跟 x86及MS 檔案讀取有關)

爛Ya~字太多都不行

2006-02-15 13:06:53 · answer #1 · answered by weilai 5 · 0 0

line1:註解
line2:傳回int值的函式,其傳入變數為unsigned char *image, int xsize, int ysize, char *filename
line3:函式開始
line4:宣告兩個long變數
line5:宣告檔案指標
line6:宣告三個long變數
line7:宣告無號數字元指標
line8:宣告字元陣列,其大小為128
line9:宣告無號數字元陣列並初始化值
line10:計算file_size
line11:header[2] = (無號數字元型態)(變數file_size AND邏輯運算 0x000000ff值);
line12:header[3] = (file_size >> 8) & 0x000000ff;//file_size位元右移8bit再AND0x000000ff
line13:header[4] = (file_size >> 16) & 0x000000ff;//file_size位元右移16bit再AND0x000000ff
line14:header[5] = (file_size >> 24) & 0x000000ff;//file_size位元右移24bit再AND0x000000ff
line15:width = xsize;//資料指定
line16:header[18] = width & 0x000000ff;//width與0x000000ff做AND後指給陣列位址18
line17:header[19] = (file_size >> 8) & 0x000000ff;//file_size右移8bit再AND0x000000ff
line18:header[20] = (file_size >> 16) & 0x000000ff;//file_size右移16bit再AND0x000000ff
line19:header[21] = (file_size >> 24) & 0x000000ff;//file_size右移24bit再AND0x000000ff
line20:height = ysize;//資料指定值
line21:header[22] = height & 0x000000ff;;//heitht與0x000000ff做AND後指給陣列位址22
line22:header[23] = (file_size >> 8) & 0x000000ff;;//file_size右移8bit再AND0x000000ff
line23:header[24] = (file_size >> 16) & 0x000000ff;//file_size右移16bit再AND0x000000ff
line24:header[25] = (file_size >> 24) & 0x000000ff//file_size右移24bit再AND0x000000ff
line25:配置大小(size_t)為xsize*ysize*3的(unsigned char *)型態的記憶體空間給image_buf
line26:if (image_buf == NULL) return -1;//若image_buf為0則傳回-1值
line27:for迴圈y
line28:for迴圈x
line29~31:指定指標內的值
line32:格式化輸出函式sprintf
line33:若開檔失敗傳回-1值,其讀取格式為wb二元檔
line34:二元檔寫入
line35:二元檔寫入
line36:關閉檔案
line37:釋放記憶體空間
line38:傳回0值return 0;
line39:函式結束

2006-02-15 13:23:41 · answer #2 · answered by ? 5 · 0 0

fedest.com, questions and answers