我正在尝试修改位图文件,为了做到这一点,我需要它的大小。
我很确定我正确阅读了标题,我使用了这些结构(顺便说一句,使用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编号总是小于属性编号,当它不同时。
答案 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有关如何读取位图的信息。