2013-02-22 163 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;