c++ - 从原始标题和图像数据创建位图

标签 c++ bitmap

我对在 C++ 中操作位图数据非常陌生,但遇到了问题。我正在尝试关注 this来自维基百科的例子。这是我正在使用的代码:

#include <iostream>
#include <fstream>
#include <Windows.h>

using namespace std;

int main()
{

    //fileheader
    BITMAPFILEHEADER* bf = new BITMAPFILEHEADER;
    bf->bfType = 66;
    bf->bfSize = 70;
    bf->bfOffBits = 54;

    //infoheader
    BITMAPINFOHEADER* bi = new BITMAPINFOHEADER;
    bi->biSize = 40;
    bi->biWidth = 2;
    bi->biHeight = 2;
    bi->biPlanes = 1;
    bi->biBitCount = 24;
    bi->biCompression = 0;
    bi->biSizeImage = 16;
    bi->biXPelsPerMeter = 2835;
    bi->biYPelsPerMeter = 2835;
    bi->biClrUsed = 0;
    bi->biClrImportant = 0;

    //image data
    unsigned char* thedata = new unsigned char;
    thedata[0] = 0;
    thedata[1] = 0;
    thedata[2] = 255;

    thedata[3] = 255;
    thedata[4] = 255;
    thedata[5] = 255;

    thedata[6] = 0;
    thedata[7] = 0;

    thedata[8] = 255;
    thedata[9] = 0;
    thedata[10] = 0;

    thedata[11] = 0;
    thedata[12] = 255;
    thedata[13] = 0;

    thedata[14] = 0;
    thedata[15] = 0;

    //dc
    HDC dc = GetDC(NULL);

    //bitmap info
    BITMAPINFO* bmi = (BITMAPINFO*)bi;

    //handle to bitmap
    HBITMAP hbmp = CreateDIBitmap(dc, bi, CBM_INIT, thedata, bmi, DIB_RGB_COLORS);

    //output to bmp....?
    ofstream outFile;
    outFile.open("outtestbmp.bmp");
    outFile << hbmp;
    outFile.close();

}

过去几天我一直在谷歌上搜索,试图弄清楚如何完成这项工作,但我似乎仍然无法让它发挥作用。

这符合没有错误,但最后outtestbmp.bmp文件是打不开的。我犯的任何重大错误(可能有几十个)阻止了它的工作吗? (我高度怀疑使用 ofstream 输出我的 bmp 数据是错误的)。

编辑:有人告诉我将 bftype 设置为 66 是错误的。正确的值是多少?

此外,我还创建了一个 .bmp 文件来说明输出内容。这是该 bmp 的十六进制数据:

42 4D 46 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18        
00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF  
FF FF 00 00 FF 00 00 00 FF 00 00 00

这是我正在输出的 .bmp 数据:

42 00 46 00 00 00 CD CD CD CD 36 00 00 00 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18 
00 00 00 00 00 10 00 00 00 13 0B 00 00 13 0B 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 
FF FF 00 00 FF 00 00 00 FF 00 00 00

最佳答案

bf->bfType == 66;

这在两个方面是错误的。首先,它是错误的值(魔法值是小字节序机器上的字节“BM”或 0x4d42),其次,它不是赋值。

然后:

unsigned char* thedata = new unsigned char;

只分配 1 个字符?

还有这个:

outFile << hbmp;

并没有按照您的想法行事。你只是在写一个句柄。您不需要创建位图,只需写出您已初始化的数据结构(一旦您使它们正确)。

为什么要更新所有内容?不需要动态分配这些东西(而且您也不会删除它)。

我通常会这样做(为简洁起见删除了一些代码):

BITMAPFILEHEADER bf;
bf.bfType = 0x4d42;
bf.bfSize = 70;
bf.bfOffBits = 54;

//infoheader
BITMAPINFOHEADER bi;
bi.biSize = 40;
bi.biWidth = 2;
etc...

//image data
unsigned char* thedata = new unsigned char[16]; // Should really calculate this properly
thedata[0] = 0;
....

//output to bmp....?
ofstream outFile;
outFile.open("outtestbmp.bmp");
outFile.write((char *)&bf,sizeof(bf));
outFile.write((char *)&bi,sizeof(bi));
outFile.write((char *)thedata, 16);
outFile.close();

关于c++ - 从原始标题和图像数据创建位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14650566/

相关文章:

c++ - 如何在 Windows 8 中获取窗口标题栏(事件和非事件)颜色?

c++ - 在 Visual "Microsoft studio 2019"上设置 OpenCV 4.1.1 有问题吗? (非法指令。)

c - 从 Windows 剪贴板获取 32 位 RGBA 图像

c++ - 专门用于成员结构的 std 模板

c++ - 在 C++ 中类应该以什么顺序声明?

c++ - 为什么第一行向右移动一个空格?

windows - 如何在 Windows 中直接分配显卡内存?

c# - Bitmap.Save,巨大的内存泄漏

android - 开始 Activity 时出现意外延迟

java - 在 Java 中创建位图的错误