【问题标题】:image data of bmp in CC中bmp的图像数据
【发布时间】:2013-11-25 21:17:31
【问题描述】:

如何将单色 bmp 图像文件(在我的情况下为 16*16 像素)转换为二进制格式?此代码读取位图信息。我必须将像素信息存储到一个数组中,并且它没有正确存储。我已经分享了代码

#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;
long data[16];
}BitMap;
#pragma pack(pop)

读取图像文件:

struct BitMap source_info;
struct Pix source_pix;

FILE *fp;
FILE *Dfp;
Dfp=fopen("filename.bin","wb")

if(!(fp=fopen("filename.bmp","rb")))
 {
    printf(" can not open file");
    exit(-1);
 }

fread(&source_info, sizeof(source_info),1,fp);
printf("%d\n",source_info.DataOffSet);
printf("%d\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%d\t",source_info.data[i]);

使用十六进制编辑器观察到的输出是

突出显示的数据我想存储在数据数组中,以便我可以在代码中进一步使用它。

但是 filename.bin 中的输出是

0  16777215 63 63 63 95 95 95
31 31       31 31 31 31 31 31

我是这个领域的新手。有人可以帮我解决我哪里出错了吗?

【问题讨论】:

  • 首先,如果您打印十六进制数字,比较值可能会更容易。
  • @JoachimPileborg 是的。实际上,如果 OP 尝试使用十六进制数字是没有问题的——它们是一样的..
  • 十六进制输出为 0x00 0xffffff 0x3f 0x3f 0x3f 0x5f 0x5f 0x5f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 你能解释一下输出是如何存储的吗?我无法获得相同的输出
  • @user2967899 由于您的最后评论,我已经更新了我的答案。

标签: c binary binaryfiles monochrome


【解决方案1】:

数据实际上没有问题。
问题是您使用了错误的方式来打印它们。

尝试替换您的代码:

printf("%d\n",source_info.DataOffSet);
printf("%d\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
    fprintf(Dfp,"%d\t",source_info.data[i]);

用这个:

printf("%x\n",source_info.DataOffSet);
printf("%x\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
    fprintf(Dfp,"%x\t",source_info.data[i]);

%d 用于有符号十进制,%x 用于十六进制。见the manual page of printfThe conversion specifier部分

已编辑:

正如您在 cmets 中发布的新问题:

十六进制输出是 0x00 0xffffff 0x3f 0x3f 0x3f 0x5f 0x5f 0x5f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 你能解释一下输出是如何存储的吗?我无法获得相同的输出 – user2967899 7 分钟前

这是我编辑的答案。

假设:您的工作平台和正常一样,short 的大小为 2 个字节,long 的大小为 4 个。
根据struct BitMap 的定义,我们知道data 字段的偏移量为0x36。比较图像我们知道数据应该是(十六进制):

data[0]: 0000 0000
data[1]: ffff ff00
......

那么你得到的结果看起来很奇怪,因为data[1]0x00ffffffff 而不是0xffffff00。然而这是正确的。这是由字节序引起的,请先阅读此 wiki 页面:http://en.wikipedia.org/wiki/Endianness
由于十六进制编辑器以实际字节顺序表示数据,并且我假设您正在使用 little-endian 机器(这个星球上的大多数 PC 都有),因此此顺序与您的数据的实际顺序相反long:

/* data in C */
unsigned long x = 305419896; /* 305419896 == 0x12345678 */

/* arithmetically the four bytes in x: */
/* 0x12 0x34 0x56 0x78 */

/* the real order to be observed in a hex-editor due to endianess: */
/* 0x78 0x56 0x34 0x12 */

/* so this holds true in C: */
unsigned char *a = &x;
assert(a[0] == 0x78);
assert(a[1] == 0x56);
assert(a[2] == 0x34);
assert(a[3] == 0x12);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2017-04-01
    • 2014-12-26
    • 1970-01-01
    • 2018-04-23
    • 2019-12-03
    • 2015-09-25
    相关资源
    最近更新 更多