特点:
- C++单个头文件,include 可用;
- 单例模式,不需要 new instance;
使用方式:
bmpWriter.saveBinaryDataAsBMP(path + ".bmp", static_cast<const unsigned char *>(ptr), m_width, m_height, m_channel);
头文件内容
#ifndef TOOLS_BMP_WRITER_HPP
#define TOOLS_BMP_WRITER_HPP
#include <fstream>
#include <iostream>
#include <vector>
namespace TOOLS {
#pragma pack(push, 1)
struct BMPHeader {
uint16_t bfType = 0;
uint32_t bfSize = 0;
uint16_t bfReserved1 = 0;
uint16_t bfReserved2 = 0;
uint32_t bfOffBits = 0;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct BMPInfoHeader {
uint32_t biSize = 0;
int32_t biWidth = 0;
int32_t biHeight = 0;
uint16_t biPlanes = 0;
uint16_t biBitCount = 0;
uint32_t biCompression = 0;
uint32_t biSizeImage = 0;
int32_t biXPelsPerMeter = 0;
int32_t biYPelsPerMeter = 0;
uint32_t biClrUsed = 0;
uint32_t biClrImportant = 0;
};
#pragma pack(pop)
class BMPWriter {
private:
size_t grayPaletteSize = 256 * 4;
unsigned char grayPalette[256 * 4] = {0};
public:
BMPWriter()
{
for (int i = 0; i < 256; ++i)
{
grayPalette[i * 4] = i;
grayPalette[i * 4 + 1] = i;
grayPalette[i * 4 + 2] = i;
grayPalette[i * 4 + 3] = 0;
}
}
~BMPWriter() = default;
static BMPWriter &getInstance()
{
static BMPWriter instance;
return instance;
}
void saveBinaryDataAsBMP(const std::string filename, const unsigned char *data, int width, int height, int depth)
{
std::ofstream file(filename, std::ios::binary);
if (!file)
{
std::cerr << "Failed to open file for writing." << std::endl;
return;
}
BMPHeader bmpHeader;
bmpHeader.bfType = 0x4D42;
bmpHeader.bfSize = sizeof(BMPHeader) + sizeof(BMPInfoHeader) + (1 == depth ? grayPaletteSize : 0) + width * height * depth;
bmpHeader.bfReserved1 = 0;
bmpHeader.bfReserved2 = 0;
bmpHeader.bfOffBits = sizeof(BMPHeader) + sizeof(BMPInfoHeader) + (1 == depth ? grayPaletteSize : 0);
BMPInfoHeader bmpInfoHeader;
bmpInfoHeader.biSize = sizeof(BMPInfoHeader);
bmpInfoHeader.biWidth = width;
bmpInfoHeader.biHeight = height;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 8 * depth;
bmpInfoHeader.biCompression = 0;
bmpInfoHeader.biSizeImage = width * height * depth;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;
file.write(reinterpret_cast<const char *>(&bmpHeader), sizeof(BMPHeader));
file.write(reinterpret_cast<const char *>(&bmpInfoHeader), sizeof(BMPInfoHeader));
if (1 == depth)
{
file.write(reinterpret_cast<const char *>(grayPalette), sizeof(grayPalette));
}
for (int y = height - 1; y >= 0; y--)
{
for (int x = 0; x < width; x++)
{
file.write(reinterpret_cast<const char *>(data + (y * width + x) * depth), depth);
}
}
file.close();
}
};
static BMPWriter &bmpWriter = BMPWriter::getInstance();
}
#endif