我从Bitmap文件获得的大小是否正确?不匹配的属性

时间:2017-12-16 12:13:34

标签: c arrays file bitmap

我正在尝试修改位图文件,为了做到这一点,我需要它的大小。

我很确定我正确阅读了标题,我使用了这些结构(顺便说一句,使用C):

#pragma pack(1)

struct bmp_fileheader
{
    unsigned char  fileMarker1; /* 'B' */
    unsigned char  fileMarker2; /* 'M' */
    unsigned int   bfSize; /* File's size */
    unsigned short unused1;
    unsigned short unused2;
    unsigned int   imageDataOffset; /* Offset to the start of image data */
};

struct bmp_infoheader
{
    unsigned int   biSize; /* Size of the info header - 40 bytes */
    signed int     width; /* Width of the image */
    signed int     height; /* Height of the image */
    unsigned short planes;
    unsigned short bitPix;
    unsigned int   biCompression;
    unsigned int   biSizeImage; /* Size of the image data */
    int            biXPelsPerMeter;
    int            biYPelsPerMeter;
    unsigned int   biClrUsed;
    unsigned int   biClrImportant;
};

#pragma pack()

在一天结束时,我得到了一个错误的结果,我认为这是因为bfSize与文件的属性不匹配。 (右键单击属性与printf bfSize不同。

根据我对此链接(https://en.wikipedia.org/wiki/BMP_file_format#Example_1)的理解,bfSize应包含整个大小,包括填充。

如果bfSize与属性不同,可以吗?

我刚才有了一个想法,你认为我的错误结果是因为我使用pragma pack读取结构,然后我继续读取文件,好像我从像素的数组开始读取?

我正在使用像

这样的东西
FILE *pf 

我读了那些结构。

我计算了像素阵列中存储的八位字节数。

然后我从pf的位置继续读取那些八位字节,根据我的逻辑,这应该是数组开始的确切位置。

感谢阅读。

编辑:ps:这些差异类似于:bfSize说 3645和它显示的属性3702,这是一个非常大的差异。 bfSize编号总是小于属性编号,当它不同时。

1 个答案:

答案 0 :(得分:1)

bfSize是文件的大小,包括标题。

biSizeImage是像素数据的大小,以字节为单位。数据从imageDataOffset开始(通常称为bfOffBits)。

使用#pragma pack(1)定义标头是正确的。在定义它们之后,你应该恢复打包,但是对于阅读它并不重要。

如果要更改图像的大小,则需要计算新扫描线大小的新高度。扫描线使用以下方法向上舍入到最近的单词:

// WIDTHBYTES takes # of bits in a scanline and rounds up to nearest word.
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)

你称之为:

int scanlineSize= WIDTHBYTES(bih.biWidth * bih.biBitCount);

从文件中读取位图信息头结构bih

另请参阅pointer file randomly changes value in middle of reading raw bitmap data有关如何读取位图的信息。