我无法在 Linux 上用 C 读取 .bmp 文件,但我可以在 raspbian 上读取(相同的代码)
I can't read .bmp file in C on Linux, but I can do it in raspbian (same code)
抱歉我的英语不好。
我试图在 Linux (Fedora 27) 上使用 gcc 读取 C 代码中的 .bmp 文件,但它不起作用,具体问题是当我使用 "fread()" 时。我 运行 在 raspbian (4.9.2-10) 上使用相同的代码并且神奇地工作,正确读取和写入 .bmp 文件。我真的不知道发生了什么,我需要帮助,拜托:'(
我使用这张图片:
https://mega.nz/#!c5hVEYTb!u4Mc3JxvrHxxpaMLpH8A-KS3_bb72_Nj9bHv1x-2keU
这是代码:
#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;
unsigned long int S=0;
struct BitMap source_info;
struct Pix source_pix;
FILE *fp;
FILE *Dfp;
fp=fopen("in.bmp","rb");
if (fp==NULL)
{
fputs("File error:", stderr);
exit(1);
}
Dfp=fopen("out.bmp","wb");
//I think maybe in this line is the problem:
fread(&source_info, sizeof(source_info),1,fp);
S=source_info.Width*source_info.Height;
source_info.pixels = (struct Pix *) malloc(sizeof(struct Pix)*S);
for(i=1;i<=S;i++)
{
//read pixel from the source file
fread(&source_pix,sizeof(struct Pix),1,fp);
source_info.pixels[i-1] = source_pix;
}
fwrite(&source_info, sizeof(BitMap),1,Dfp);
// write pixels to destination file
for(i=1;i<=S;i++)
{
fwrite(&source_info.pixels[i-1],sizeof(struct Pix),1,Dfp);
}
fclose(fp);
fclose(Dfp);
return 0;
}
您没有在体系结构之间使用固定大小的类型。例如在 32 位平台上 long
是 32 位,但在 64 位平台上 long
是 64 位,这就是为什么在 64 位平台上它无法读取 headers正确。解决方案是使用 stdint
.
中的定义
#include <stdint.h>
#pragma pack(push, 1)
typedef struct Pix
{
uint8_t R, G, B;
int32_t BW;
}
Pix;
typedef struct BitMap
{
int16_t Signature;
int32_t Reserved1;
int32_t Reserved2;
int32_t DataOffSet;
int32_t Size;
int32_t Width;
int32_t Height;
int16_t Planes;
int16_t BitsPerPixel;
int32_t Compression;
int32_t SizeImage;
int32_t XPixelsPreMeter;
int32_t YPixelsPreMeter;
int32_t ColorsUsed;
int32_t ColorsImportant;
struct Pix *pixels;
}
BitMap;
#pragma pack(pop)
抱歉我的英语不好。
我试图在 Linux (Fedora 27) 上使用 gcc 读取 C 代码中的 .bmp 文件,但它不起作用,具体问题是当我使用 "fread()" 时。我 运行 在 raspbian (4.9.2-10) 上使用相同的代码并且神奇地工作,正确读取和写入 .bmp 文件。我真的不知道发生了什么,我需要帮助,拜托:'(
我使用这张图片: https://mega.nz/#!c5hVEYTb!u4Mc3JxvrHxxpaMLpH8A-KS3_bb72_Nj9bHv1x-2keU
这是代码:
#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;
unsigned long int S=0;
struct BitMap source_info;
struct Pix source_pix;
FILE *fp;
FILE *Dfp;
fp=fopen("in.bmp","rb");
if (fp==NULL)
{
fputs("File error:", stderr);
exit(1);
}
Dfp=fopen("out.bmp","wb");
//I think maybe in this line is the problem:
fread(&source_info, sizeof(source_info),1,fp);
S=source_info.Width*source_info.Height;
source_info.pixels = (struct Pix *) malloc(sizeof(struct Pix)*S);
for(i=1;i<=S;i++)
{
//read pixel from the source file
fread(&source_pix,sizeof(struct Pix),1,fp);
source_info.pixels[i-1] = source_pix;
}
fwrite(&source_info, sizeof(BitMap),1,Dfp);
// write pixels to destination file
for(i=1;i<=S;i++)
{
fwrite(&source_info.pixels[i-1],sizeof(struct Pix),1,Dfp);
}
fclose(fp);
fclose(Dfp);
return 0;
}
您没有在体系结构之间使用固定大小的类型。例如在 32 位平台上 long
是 32 位,但在 64 位平台上 long
是 64 位,这就是为什么在 64 位平台上它无法读取 headers正确。解决方案是使用 stdint
.
#include <stdint.h>
#pragma pack(push, 1)
typedef struct Pix
{
uint8_t R, G, B;
int32_t BW;
}
Pix;
typedef struct BitMap
{
int16_t Signature;
int32_t Reserved1;
int32_t Reserved2;
int32_t DataOffSet;
int32_t Size;
int32_t Width;
int32_t Height;
int16_t Planes;
int16_t BitsPerPixel;
int32_t Compression;
int32_t SizeImage;
int32_t XPixelsPreMeter;
int32_t YPixelsPreMeter;
int32_t ColorsUsed;
int32_t ColorsImportant;
struct Pix *pixels;
}
BitMap;
#pragma pack(pop)