我想在B中将bmp文件加载到内存中。我发现了许多不同类型的BmpFileHeader和BmpInfoHeader结构。我从msdn.microsoft.com获取的最后一个,但它仍然无法从二进制文件中正确读取。使用测试文件lena 图片大小:-1076791624 无法分配内存
我错过了什么?感谢。
#include <stdio.h>
#include <stdlib.h>
typedef struct tagBITMAPFILEHEADER {
unsigned short bfType;
unsigned int bfSize;
short bfReserved1;
short bfReserved2;
unsigned int bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned int biSize;
int biWidth;
int biHeight;
short biPlanes;
short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BITMAPINFOHEADER;
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("Usage: %s input.bmp\n", argv[0]);
exit(-1);
}
FILE *filePtr;
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER bitmapInfoHeader;
unsigned char *bitmapImage;
int imageIdx=0;
unsigned char tempRGB;
filePtr = fopen(argv[1],"rb");
if (filePtr == NULL)
{
printf("File could not opened\n");
exit(-1);
}
//read the bitmap file header
fread(&bitmapFileHeader, sizeof(bitmapFileHeader), 1, filePtr);
if (bitmapFileHeader.bfType !=0x4D42)
{
fclose(filePtr);
printf("Not a bmp file\n");
exit(-1);
}
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
bitmapImage = (unsigned char*)malloc(sizeof(unsigned char)*bitmapInfoHeader.biSizeImage);
printf("Image Size: %d\n", bitmapInfoHeader.biSizeImage);
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
printf("Memory could not be allocated\n");
exit(-1);
}
//swap the r and b values to get RGB (bitmap is BGR)
for (imageIdx = 0; imageIdx < bitmapInfoHeader.biSizeImage; imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
int i;
for(i = 0; i < bitmapInfoHeader.biSizeImage; i+=3){
printf("R: %c G: %c B: %c\n", bitmapImage[i], bitmapImage[i + 1], bitmapImage[i + 2]);
}
fclose(filePtr);
return 0;
}
答案 0 :(得分:0)
您的bitmapInfoHeader
未初始化!
即,您读取bitmapFileHeader
,然后将文件指针设置为实际位图数据的位置。但是您没有阅读bitmapInfoHeader
,其中包含有关位图的所有信息(尺寸,bpp等)。
P.S。 下次请尝试调试你的代码发布问题。
答案 1 :(得分:0)
我要做的第一件事是在这些标题的byte layout上找到权威声明,然后假设您要继续使用已定义的结构,在字段上添加一些断言抵消,例如:
assert(offsetof(BITMAPFILEHEADER, bfType) == 0); // or whatever
assert(offsetof(BITMAPFILEHEADER, bfSize) == 2); // or whatever
assert(offsetof(BITMAPFILEHEADER, bfOffBits) == 10); // or whatever
etc.
有可能你使用unsigned int,short等加上你的编译器选项(特别是结构打包)可能意味着你的struct字段与实际的BMP文件数据不匹配(偏移量,也许是长度)。
答案 2 :(得分:0)
存在多种版本的BMP文件格式,其中大多数都在标题大小上有所不同。如果您希望能够读取所有有效的BMP文件,则需要全部支持它们。 lena图像似乎是Windows V3版本。
Wikipedia中对不同版本有很好的描述。
此外,我没有看到代码中没有字节序处理。如果你的机器不是小端,那就不行了。
最后,结构成员的对齐是一个问题。您的编译器很可能在偏移量4处对齐 bfSize 成员,但它应该在偏移量2处。(有关解决方案,请参阅Wikipedia文章。)