C++ 如何生成位图头数据,然后使用c++;

C++ 如何生成位图头数据,然后使用c++;,c++,image,bitmap,C++,Image,Bitmap,我想创建一个没有任何库的位图文件头。这是我的图像数据: width = 3px; height = 10px; bits_per_pixle = 24; 我如何为它的头生成54字节数据,然后写入文件?我对此有很多问题。我不知道如何用十六进制将数据写入文件。我不知道如何用4个字节来写文件大小,等等。。有人能帮我吗?谢谢 #include <iostream> #include <fstream> #include <iomanip> using namesp

我想创建一个没有任何库的位图文件头。这是我的图像数据:

width = 3px;
height = 10px;
bits_per_pixle = 24;
我如何为它的头生成
54字节
数据,然后写入文件?我对此有很多问题。我不知道如何用十六进制将数据写入文件。我不知道如何用4个字节来写文件大小,等等。。有人能帮我吗?谢谢

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

int main()
{
    int w = 3;
    int h = 10;
    int bits_per_pixle = 24;
    ofstream des("file.bmp", ios::binary);

    return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
int w=3;
int h=10;
整数位每像素=24;
流des(“file.bmp”,ios::binary);
返回0;
}
使用此结构:


我已经为您编写了函数的一个版本。我测试了它,它成功地工作了

函数
createRawBitmap24()
创建位图图像,无需压缩,每像素24位:

struct Color24
{
    uint8_t red;
    uint8_t green;
    uint8_t blue;
};
typedef std::vector<std::vector<Color24>> Image24;
bool check(const Image24 & img)
{
    // check the shape
    bool valid(!img.empty());
    if(valid)
    {
        size_t line_size(img[0].size());
        for(size_t i = 1; valid && (i < img.size()); ++i)
        {
            if(img.at(i).size() != line_size)
                valid = false;
        }
    }
    else
        valid = false;
    return valid;
}
bool createRawBitmap24(const std::string & file_path, const Image24 & img)
{
    bool success(false);

    if(check(img))
    {
        // ----- create the image in bmp format -----

        // find the padding size
        uint8_t padding_size(0);
        size_t n = img[0].size()*3;
        while(((n+padding_size) % 4) != 0)
            ++padding_size;

        // build the raw content
        const uint32_t ris = static_cast<uint32_t>(img.size()*(img[0].size()*3 + padding_size)); // raw image size
        uint8_t * raw_content = new uint8_t[ris];

        size_t cursor(0);
        for(int i = static_cast<int>(img.size()-1); i >= 0; --i) // read lines in reverse order
        {
            for(const Color24 & pixel : img.at(static_cast<size_t>(i)))
            {
                raw_content[cursor++] = pixel.blue;
                raw_content[cursor++] = pixel.green;
                raw_content[cursor++] = pixel.red;
            }
            for(size_t j = 0; j < padding_size; ++j)
            {
                raw_content[cursor++] = 0xFF;
            }
        }

        // build the header
        const uint32_t hs(54); // header size
        const uint32_t fs = (hs + ris); // file size
        const uint32_t width = static_cast<uint32_t>(img[0].size()); // image width (without padding)
        const uint32_t height = static_cast<uint32_t>(img.size()); // image height (without padding)
        const uint32_t reso(2835); // resolution, ~72 DPI

        const uint8_t header[hs] = {
            'B', 'M',
            static_cast<uint8_t>(fs & 0xFF), static_cast<uint8_t>((fs >> 8) & 0xFF), static_cast<uint8_t>((fs >> 16) & 0xFF), static_cast<uint8_t>((fs >> 24) & 0xFF),
            0, 0,
            0, 0,
            static_cast<uint8_t>(hs & 0xFF), static_cast<uint8_t>((hs >> 8) & 0xFF), static_cast<uint8_t>((hs >> 16) & 0xFF), static_cast<uint8_t>((hs >> 24) & 0xFF),
            40, 0, 0, 0,
            static_cast<uint8_t>(width & 0xFF), static_cast<uint8_t>((width >> 8) & 0xFF), static_cast<uint8_t>((width >> 16) & 0xFF), static_cast<uint8_t>((width >> 24) & 0xFF),
            static_cast<uint8_t>(height & 0xFF), static_cast<uint8_t>((height >> 8) & 0xFF), static_cast<uint8_t>((height >> 16) & 0xFF), static_cast<uint8_t>((height >> 24) & 0xFF),
            1, 0,
            24, 0,
            0, 0, 0, 0,
            static_cast<uint8_t>(ris & 0xFF), static_cast<uint8_t>((ris >> 8) & 0xFF), static_cast<uint8_t>((ris >> 16) & 0xFF), static_cast<uint8_t>((ris >> 24) & 0xFF),
            static_cast<uint8_t>(reso & 0xFF), static_cast<uint8_t>((reso >> 8) & 0xFF), static_cast<uint8_t>((reso >> 16) & 0xFF), static_cast<uint8_t>((reso >> 24) & 0xFF),
            static_cast<uint8_t>(reso & 0xFF), static_cast<uint8_t>((reso >> 8) & 0xFF), static_cast<uint8_t>((reso >> 16) & 0xFF), static_cast<uint8_t>((reso >> 24) & 0xFF),
            0, 0, 0, 0,
            0, 0, 0, 0
        };

        // ----- Write the content in the file -----
        std::ofstream out_s(file_path, std::ofstream::binary);
        if(out_s)
        {
            for(size_t i = 0; i < hs; ++i)
                out_s << header[i];
            for(size_t i = 0; i < ris; ++i)
                out_s << raw_content[i];

            out_s.close();
            success = true;
        }
        delete [] raw_content;
    }
    return success;
}
struct Color24
{
uint8_t红色;
uint8_t绿色;
uint8_t蓝;
};
typedef std::矢量图像24;
布尔检查(常量图像24和img)
{
//检查形状
bool有效(!img.empty());
如果(有效)
{
大小(img[0].size());
对于(size_t i=1;有效&&(i=0;--i)//按相反顺序读取行
{
对于(恒定颜色24和像素:img.at(静态投影(i)))
{
原始内容[cursor++]=pixel.blue;
原始内容[cursor++]=pixel.green;
原始内容[cursor++]=pixel.red;
}
对于(大小j=0;j>8)和0xFF)、静态强制转换((fs>>16)和0xFF)、静态强制转换((fs>>24)和0xFF),
0, 0,
0, 0,
静态播放(hs&0xFF)、静态播放((hs>>8)和0xFF)、静态播放((hs>>16)和0xFF)、静态播放((hs>>24)和0xFF),
40, 0, 0, 0,
静态(宽度和0xFF)、静态(宽度>>8)和0xFF、静态(宽度>>16)和0xFF、静态(宽度>>24)和0xFF、,
静态投影(高度和0xFF)、静态投影((高度>>8)和0xFF)、静态投影((高度>>16)和0xFF)、静态投影((高度>>24)和0xFF),
1, 0,
24, 0,
0, 0, 0, 0,
静态播放(ris&0xFF)、静态播放((ris>>8)和0xFF)、静态播放((ris>>16)和0xFF)、静态播放((ris>>24)和0xFF),
静态(分辨率和0xFF)、静态(分辨率>>8)和0xFF)、静态(分辨率>>16)和0xFF)、静态(分辨率>>24)和0xFF、,
静态(分辨率和0xFF)、静态(分辨率>>8)和0xFF)、静态(分辨率>>16)和0xFF)、静态(分辨率>>24)和0xFF、,
0, 0, 0, 0,
0, 0, 0, 0
};
//----在文件中写入内容-----
std::ofstream out(文件路径,std::ofstream::binary);
如果(不适用)
{
用于(尺寸i=0;iOutsOS做任何事情都没有任何库是困难的,因为C++中的很多都是在库中(例如,包括流)。你能清楚哪些是你不允许使用的库吗?比如说,Windows库如何?用十六进制写数据(你的意思是‘二进制’,‘十六进制’没有任何意义。使用
ostream::write
方法。实际上,您只需填写54字节的数据结构,然后调用
ostream::write
将数据写入文件。@john我可以使用ofstream等。但我不应该使用额外的库来处理位图文件。这可能很有趣:。我这样做是为了标签被标记,但它肯定也在C++中工作(修改很小,可能是)。注意,长是4字节签名,dWord是4字节未签名,Word是2字节未签名。
struct Color24
{
    uint8_t red;
    uint8_t green;
    uint8_t blue;
};
typedef std::vector<std::vector<Color24>> Image24;
bool check(const Image24 & img)
{
    // check the shape
    bool valid(!img.empty());
    if(valid)
    {
        size_t line_size(img[0].size());
        for(size_t i = 1; valid && (i < img.size()); ++i)
        {
            if(img.at(i).size() != line_size)
                valid = false;
        }
    }
    else
        valid = false;
    return valid;
}
bool createRawBitmap24(const std::string & file_path, const Image24 & img)
{
    bool success(false);

    if(check(img))
    {
        // ----- create the image in bmp format -----

        // find the padding size
        uint8_t padding_size(0);
        size_t n = img[0].size()*3;
        while(((n+padding_size) % 4) != 0)
            ++padding_size;

        // build the raw content
        const uint32_t ris = static_cast<uint32_t>(img.size()*(img[0].size()*3 + padding_size)); // raw image size
        uint8_t * raw_content = new uint8_t[ris];

        size_t cursor(0);
        for(int i = static_cast<int>(img.size()-1); i >= 0; --i) // read lines in reverse order
        {
            for(const Color24 & pixel : img.at(static_cast<size_t>(i)))
            {
                raw_content[cursor++] = pixel.blue;
                raw_content[cursor++] = pixel.green;
                raw_content[cursor++] = pixel.red;
            }
            for(size_t j = 0; j < padding_size; ++j)
            {
                raw_content[cursor++] = 0xFF;
            }
        }

        // build the header
        const uint32_t hs(54); // header size
        const uint32_t fs = (hs + ris); // file size
        const uint32_t width = static_cast<uint32_t>(img[0].size()); // image width (without padding)
        const uint32_t height = static_cast<uint32_t>(img.size()); // image height (without padding)
        const uint32_t reso(2835); // resolution, ~72 DPI

        const uint8_t header[hs] = {
            'B', 'M',
            static_cast<uint8_t>(fs & 0xFF), static_cast<uint8_t>((fs >> 8) & 0xFF), static_cast<uint8_t>((fs >> 16) & 0xFF), static_cast<uint8_t>((fs >> 24) & 0xFF),
            0, 0,
            0, 0,
            static_cast<uint8_t>(hs & 0xFF), static_cast<uint8_t>((hs >> 8) & 0xFF), static_cast<uint8_t>((hs >> 16) & 0xFF), static_cast<uint8_t>((hs >> 24) & 0xFF),
            40, 0, 0, 0,
            static_cast<uint8_t>(width & 0xFF), static_cast<uint8_t>((width >> 8) & 0xFF), static_cast<uint8_t>((width >> 16) & 0xFF), static_cast<uint8_t>((width >> 24) & 0xFF),
            static_cast<uint8_t>(height & 0xFF), static_cast<uint8_t>((height >> 8) & 0xFF), static_cast<uint8_t>((height >> 16) & 0xFF), static_cast<uint8_t>((height >> 24) & 0xFF),
            1, 0,
            24, 0,
            0, 0, 0, 0,
            static_cast<uint8_t>(ris & 0xFF), static_cast<uint8_t>((ris >> 8) & 0xFF), static_cast<uint8_t>((ris >> 16) & 0xFF), static_cast<uint8_t>((ris >> 24) & 0xFF),
            static_cast<uint8_t>(reso & 0xFF), static_cast<uint8_t>((reso >> 8) & 0xFF), static_cast<uint8_t>((reso >> 16) & 0xFF), static_cast<uint8_t>((reso >> 24) & 0xFF),
            static_cast<uint8_t>(reso & 0xFF), static_cast<uint8_t>((reso >> 8) & 0xFF), static_cast<uint8_t>((reso >> 16) & 0xFF), static_cast<uint8_t>((reso >> 24) & 0xFF),
            0, 0, 0, 0,
            0, 0, 0, 0
        };

        // ----- Write the content in the file -----
        std::ofstream out_s(file_path, std::ofstream::binary);
        if(out_s)
        {
            for(size_t i = 0; i < hs; ++i)
                out_s << header[i];
            for(size_t i = 0; i < ris; ++i)
                out_s << raw_content[i];

            out_s.close();
            success = true;
        }
        delete [] raw_content;
    }
    return success;
}