繁体   English   中英

如何使用 c++ 创建 BMP 文件?

[英]How do I create BMP files using c++?

我正在尝试创建一个 class 来保存给定像素的 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 图片,这不是我想要的。

当然你想念#pragma pack #pragma pack(push,1) / #pragma pack(pop)包裹你的结构

当结构代表 memory 布局并且应该没有填充时,即使有未对齐的数据,也应该打包结构。

对于这种情况,将static_assert设置为预期的sizeof值非常有帮助。

此外,当你打包它们时, RGBQuad将变成只有 3 个字节。 如果您真的想要三倍,建议将其重命名为三倍。 否则添加虚拟或 alpha 字节以完成它到四边形。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM