如何使用 C++ 创建 BMP 文件?
Posted
技术标签:
【中文标题】如何使用 C++ 创建 BMP 文件?【英文标题】:How do I create BMP files using c++? 【发布时间】:2021-02-22 15:03:05 【问题描述】:我正在尝试创建一个在给定像素的情况下保存 BMP 图像的类。 这是我的 .h:
#ifndef _IMAGE_SAVER_
#define _IMAGE_SAVER_
#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#include <bitset>
//#define _DEBUG_
#ifdef _DEBUG_
#include <iostream>
#endif
#include <stdint.h>
typedef struct BMFileHeader
uint16_t _bfType = 19778;
uint32_t _bfSize;
uint16_t _bfReserved1 = 0;
uint16_t _bfReserved2 = 0;
uint32_t _bfOffBits = 54;
BMFileHeader;
typedef struct BMInfoHeader
uint32_t _biSize = 40;
uint32_t _biWidth;
uint32_t _biHeight;
uint16_t _biPlanes = 1;
uint16_t _biBitCount = 24;
uint32_t _biCompression = 0;
uint32_t _biSizeImage = 0;
uint32_t _biXPelsPerMeter = 3780;
uint32_t _biYPelsPerMeter = 3780;
uint32_t _biClrUser = 0;
uint32_t _biClrImportant = 0;
BMInfoHeader;
typedef struct RGBQuad
uint8_t _blue;
uint8_t _green;
uint8_t _red;
RGBQuad;
class ImageSaver
public:
ImageSaver() = delete;
ImageSaver(const uint32_t& height, const uint32_t& width, const std::vector<RGBQuad>& pixels) : _RGBQuad_Vector(pixels)
this->_Info_Header._biHeight = height;
this->_Info_Header._biWidth = width;
;
void saveImage(const std::string& fileName);
protected:
void setFileSize();
void createImageFile(const std::string& fileName);
private:
BMFileHeader _File_Header;
BMInfoHeader _Info_Header;
std::vector<RGBQuad> _RGBQuad_Vector;
;
#endif
这是我的 .cpp:
#include "ImageSaver.h"
void ImageSaver::saveImage(const std::string& fileName)
this->setFileSize();
this->createImageFile(fileName);
void ImageSaver::setFileSize()
uint32_t height = this->_Info_Header._biHeight;
uint32_t width = this->_Info_Header._biWidth;
this->_File_Header._bfSize = 3 * (height * width) + 54;
void ImageSaver::createImageFile(const std::string& fileName)
std::ofstream imageFile(fileName + ".bmp", std::ios::binary);
imageFile.write((char*)&this->_File_Header, 14);
imageFile.write((char*)&this->_Info_Header, 40);
size_t numberOfPixels = this->_Info_Header._biHeight * this->_Info_Header._biWidth;
for (int i = 0; i < numberOfPixels; i++)
imageFile.write((char*)&(this->_RGBQuad_Vector[i]), 3);
imageFile.close();
这是我的 main.cpp:
#include "ImageSaver.h"
#include <vector>
#include <iostream>
int main()
std::vector<RGBQuad> pixels;
for (unsigned i = 0; i < 512 * 512; i++)
RGBQuad pixel;
pixel._blue = 0;
pixel._green = 255;
pixel._red = 255;
pixels.push_back(pixel);
ImageSaver im(512, 512, pixels);
im.saveImage("scene1");
std::cout << "ESTOP0" << std::endl;
return 0;
每当我尝试创建图像文件时,它都会显示该图像文件已损坏,尽管在我看来我一直在正确遵循 BMP 格式。我分析了原始二进制数据,数据似乎(对我来说)是正确的。 GIMP 可以打开图片,但它会给出一个黑色的 512x512 图片,这不是我想要的。
【问题讨论】:
#define _IMAGE_SAVER_
该名称保留给语言实现。通过定义这样的宏,您的程序的行为将是不确定的。你应该选择另一个头后卫。
获取一个十六进制编辑器(有几个是免费的),看看你的输出是否偏离了你期望的格式。您所要做的就是使用可用的工具来分析您的代码真正在做什么。
【参考方案1】:
你肯定想念#pragma pack
。用#pragma pack(push,1)
/#pragma pack(pop)
包裹你的结构
当结构代表内存布局并且不应该有填充时,即使有未对齐的数据,也要打包结构。
在这种情况下,将static_assert
设置为预期的sizeof
值非常有帮助。
另外,当你打包它们时,RGBQuad
将变成只有 3 个字节。如果您真的想要三倍,建议将其重命名为三倍。否则添加 dummy 或 alpha 字节以完成四边形。
【讨论】:
以上是关于如何使用 C++ 创建 BMP 文件?的主要内容,如果未能解决你的问题,请参考以下文章
我需要使用 C++ 代码创建单色 .bmp 签名文件,但无法创建