难以写入位图文件
Difficulty Writing to a Bitmap File
我开始关注 Casey Muratori 的优秀 Handmade Hero Stream,最近受到启发,从头开始编写 BMP 图像加载器。
我创建了一个结构来填充位图的值Header
#pragma pack(push, 1)
struct bitmap_header {
uint16_t FType;
uint32_t FSize;
uint16_t Reserved_1;
uint16_t Reserved_2;
uint32_t BitmapOffset;
uint32_t Size;
int32_t Width;
int32_t Height;
uint16_t Planes;
uint16_t BitsPerPixel;
uint32_t Compression;
uint32_t SizeOfBMP;
int32_t HorzResolution;
int32_t VertResolution;
uint32_t ColorsUsed;
uint32_t ColorsImportant;
};
#pragma pack(pop)
然后我在入口处填写了值
bitmap_header Header = {};
Header.FType = 0x4D42; // Magic Value Here
Header.FSize = sizeof(Header) + OutputPixelSize; // entire file size
Header.BitmapOffset = sizeof(Header);
Header.Size = sizeof(Header) - 14; // Size of the Header exluding the above
Header.Width = OutputWidth;
Header.Height = -(int32_t)OutputHeight;
Header.Planes = 1;
Header.BitsPerPixel = 24;
Header.Compression= 0;
Header.SizeOfBMP = OutputPixelSize;
Header.HorzResolution = 0;
Header.VertResolution = 0;
Header.ColorsUsed = 0;
Header.ColorsImportant = 0;
我创建了一个32位无符号整型指针来存放像素数据,然后将像素数据写入一个颜色。
uint32_t OutputPixelSize = sizeof(uint32_t) * OutputWidth * OutputHeight;
uint32_t *OutputPixels = (uint32_t *)malloc(OutputPixelSize);
uint32_t *Out = OutputPixels;
for (uint32_t Y = 0; Y < OutputHeight; ++Y) {
for (uint32_t X = 0; X < OutputWidth; ++X) {
*Out++ = 0xFF0000FF;
}
}
最后,我使用标准的 fwrite() 函数将数据写入了一个 bmp 文件
FILE* OutFile = fopen("test.bmp", "wb");
if (OutFile) {
fwrite(&Header, sizeof(Header), 1, OutFile);
fwrite(&OutputPixels, sizeof(OutputPixelSize), 1, OutFile);
fclose(OutFile);
}
程序运行,创建文件;但是上述文件不被任何程序识别。我将它的 header 与一个有效的 bmp 文件进行了比较,除了文件大小之外它们是相似的。我不知道我是否将数据正确写入文件?
OutputPixelSize
是一个 uint32_t
。因此 sizeof(OutputPixelSize)
将是 4。所以
fwrite(&OutputPixels, sizeof(OutputPixelSize), 1, OutFile);
只向文件写入 4 个字节。
另外&OutputPixels
是数据指针的地址,不是数据指针。您应该将 OutputPixels
传递给 fwrite
。尝试:
fwrite(OutputPixels, 1, OutputPixelSize, OutFile);
我开始关注 Casey Muratori 的优秀 Handmade Hero Stream,最近受到启发,从头开始编写 BMP 图像加载器。
我创建了一个结构来填充位图的值Header
#pragma pack(push, 1)
struct bitmap_header {
uint16_t FType;
uint32_t FSize;
uint16_t Reserved_1;
uint16_t Reserved_2;
uint32_t BitmapOffset;
uint32_t Size;
int32_t Width;
int32_t Height;
uint16_t Planes;
uint16_t BitsPerPixel;
uint32_t Compression;
uint32_t SizeOfBMP;
int32_t HorzResolution;
int32_t VertResolution;
uint32_t ColorsUsed;
uint32_t ColorsImportant;
};
#pragma pack(pop)
然后我在入口处填写了值
bitmap_header Header = {};
Header.FType = 0x4D42; // Magic Value Here
Header.FSize = sizeof(Header) + OutputPixelSize; // entire file size
Header.BitmapOffset = sizeof(Header);
Header.Size = sizeof(Header) - 14; // Size of the Header exluding the above
Header.Width = OutputWidth;
Header.Height = -(int32_t)OutputHeight;
Header.Planes = 1;
Header.BitsPerPixel = 24;
Header.Compression= 0;
Header.SizeOfBMP = OutputPixelSize;
Header.HorzResolution = 0;
Header.VertResolution = 0;
Header.ColorsUsed = 0;
Header.ColorsImportant = 0;
我创建了一个32位无符号整型指针来存放像素数据,然后将像素数据写入一个颜色。
uint32_t OutputPixelSize = sizeof(uint32_t) * OutputWidth * OutputHeight;
uint32_t *OutputPixels = (uint32_t *)malloc(OutputPixelSize);
uint32_t *Out = OutputPixels;
for (uint32_t Y = 0; Y < OutputHeight; ++Y) {
for (uint32_t X = 0; X < OutputWidth; ++X) {
*Out++ = 0xFF0000FF;
}
}
最后,我使用标准的 fwrite() 函数将数据写入了一个 bmp 文件
FILE* OutFile = fopen("test.bmp", "wb");
if (OutFile) {
fwrite(&Header, sizeof(Header), 1, OutFile);
fwrite(&OutputPixels, sizeof(OutputPixelSize), 1, OutFile);
fclose(OutFile);
}
程序运行,创建文件;但是上述文件不被任何程序识别。我将它的 header 与一个有效的 bmp 文件进行了比较,除了文件大小之外它们是相似的。我不知道我是否将数据正确写入文件?
OutputPixelSize
是一个 uint32_t
。因此 sizeof(OutputPixelSize)
将是 4。所以
fwrite(&OutputPixels, sizeof(OutputPixelSize), 1, OutFile);
只向文件写入 4 个字节。
另外&OutputPixels
是数据指针的地址,不是数据指针。您应该将 OutputPixels
传递给 fwrite
。尝试:
fwrite(OutputPixels, 1, OutputPixelSize, OutFile);