2013-02-22 160 views
1

我寫了一個代碼來簡單地讀/寫(複製)* .bmp文件。但是有些問題我的程序一遍又一遍地重複着......我的意思是看起來好像有一段時間(真正的)循環在裏面或什麼的。繼承人我的代碼:讀取/寫入bmp文件

#include <stdio.h> 
#include <stdlib.h> 

#pragma pack(push, 1) 
typedef struct Pix 
{ 
    unsigned char R; 
    unsigned char G; 
    unsigned char B; 
    unsigned char L; 
    int BW; 
}Pix; 
#pragma pack(pop) 

#pragma pack(push, 1) 
typedef struct BitMap 
{ 
    short Signature; 
    long Reserved1; 
    long Reserved2; 
    long DataOffSet; 

    long Size; 
    long Width; 
    long Height; 
    short Planes; 
    short BitsPerPixel; 
    long Compression; 
    long SizeImage; 
    long XPixelsPreMeter; 
    long YPixelsPreMeter; 
    long ColorsUsed; 
    long ColorsImportant; 
    struct Pix *pixels 
}BitMap; 
#pragma pack(pop) 

int main(int argc, char **argv) 
{ 

unsigned long int i=0;//to count pixels readed 
unsigned long int S=0;//number of pixcels to read 

struct BitMap source_info;//to store bitmap info header 
struct Pix source_pix;// to store pixcels 

FILE *fp;//file pointer for source file 
FILE *Dfp;//file ponter for distenation file 

if(!(fp=fopen("in.bmp","rb")))//open in binery read mode 
{ 
printf(" can not open file");//prind and exit if file open error 
exit(-1); 
} 


Dfp=fopen("out.bmp","wb");//opne in binery write mode 
//read the headers to souirce file 
fread(&source_info, (sizeof(long)*3 + sizeof(short)),1,fp); 

//calucate the number of pix to read 
S=source_info.Width*source_info.Height; 
source_info.pixels = (struct Pix *) malloc(sizeof(struct Pix)*S); 

//read pixcels 
for(i=1;i<=S;i++) 
{ 
//read pixcel form source file 
fread(&source_pix,sizeof(struct Pix),1,fp); 
source_info.pixels[i-1] = source_pix; 
} 

// write header to dest file 
fwrite(&source_info, (sizeof(long)*3 + sizeof(short)),1,Dfp); 
// write pixels to dest file 
for(i=1;i<=S;i++) 
{ 
    fwrite(&source_info.pixels[i-1],sizeof(struct Pix),1,Dfp); 
} 

//close all fiels 
fclose(fp); 
fclose(Dfp); 
return 0; 
} 
+0

你不應該讀/使用'FILE *'寫的二進制文件,而使用讀/寫系統-calls。 – 2013-02-22 11:19:42

+0

@BrianBrown延伸我的答案。 – 2013-02-22 11:33:35

+0

有關各種可能性的信息可以存儲在一個所謂的bmp文件中:http://en.wikipedia。org/wiki/BMP_file_format – alk 2013-02-22 11:50:51

回答

3

您嘗試的示例圖像讀取的像素數(S)爲3762821376。這顯然太大了。

查看BMP-spec文件,看看您使用的struct BitMap是否正確。

編輯1

更改這些:

fread(&source_info, (sizeof(long)*3 + sizeof(short)),1,fp); 
... 
fwrite(&source_info, (sizeof(long)*3 + sizeof(short)),1,Dfp); 

fread(&source_info, sizeof(source_info),1,fp); 
... 
fwrite(&source_info, sizeof(source_info),1,Dfp); 

現在複製了我的測試.BMP罰款。

編輯2:

我覺得你的機器上的顏色切換問題就來了,因爲你做source_info.pixels = ...。您應該使用自己的指針Pix* pixels = malloc...,並在循環中將source_info.pixels更改爲pixels。只是沒有你的malloc分配到SOURCE_INFO結構,它應該是罰款

+0

按照你的寫法改變了它,但現在出現了不同的問題。它複製一個bmp圖像,但也改變它的顏色:/檢查這個示例圖像的代碼:http://imageshack.us/photo/my-images/208/39057820.png/ – 2013-02-22 11:37:27

+0

我的顏色不切換! – 2013-02-22 11:41:54

+0

奇怪,因爲我的,看看:http://imageshack.us/photo/my-images/266/ouuut.png/它的我的輸出圖像,out.bmp – 2013-02-22 11:43:23

1

你訪問到未inited因爲當你fread的文件頭數據,你僅僅是第一4 fields後停止source_info.Widthsource_info.Height數據。

因此,source_info的其他字段可能包含垃圾數據。 (expecially widthheight因爲他們會影響下一循環)

確保與

fread(&source_info, sizeof(BitMap),1,fp); 

然後閱讀完整的頭改變

fread(&source_info, (sizeof(long)*3 + sizeof(short)),1,fp); 

確保正確地傾倒出於同樣的原因,chainging

fwrite(&source_info, (sizeof(long)*3 + sizeof(short)),1,Dfp); 

fwrite(&source_info, sizeof(BitMap),1,Dfp); 
0

您需要跳過複製Pix指針,它可以在您想要的單個結構內工作。

fread(&source_info, (sizeof(BitMap) - sizeof(struct Pix*)),1,fp); 

順便說一句,代碼生成較小的文件大小,如果你定義在PIX爲

typedef struct Pix 
{ 
    unsigned char R; 
    unsigned char G; 
    unsigned char B; 
}Pix;