读/写bmp文件

时间:2013-02-22 11:16:17

标签: c file fwrite fread 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;
}

3 个答案:

答案 0 :(得分:3)

您尝试的样本图像的读取像素数(S)为3762821376。这显然太大了。

查看BMP规范,您使用的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结构中,它应该没问题

答案 1 :(得分:1)

您正在访问未被引用的source_info.Widthsource_info.Height数据,因为当您fread文件的标题数据时,您只需在第一个4 fields之后停止

因此source_info的其他字段可能包含垃圾数据。 (特别是widthheight会导致它们影响下一个循环)

确保阅读完整的标题更改

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

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

然后确保正确地转储它,出于同样的原因,chainging

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

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

答案 2 :(得分: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;
相关问题