Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从零开始制作位图的C++麻烦_C++_Winapi_Bitmap - Fatal编程技术网

从零开始制作位图的C++麻烦

从零开始制作位图的C++麻烦,c++,winapi,bitmap,C++,Winapi,Bitmap,我正在尝试从头开始制作位图。我有一个已知大小的RGB值的字节数组,我想生成一个HBITMAP 为了进一步澄清,我使用的字节数组纯粹是RGB值 我已确保所有变量都已设置且正确,我相信问题与lpvBits有关。在过去的几天里,我一直在为此做大量的研究,但我找不到任何对我有意义的东西 出于测试目的,宽度=6,高度=1 代码: CreateBitmap的第三个参数应该是3,而不是1。有三种颜色平面:红色、绿色和蓝色 此外,如果将高度设置为大于1的任何值,则需要用零填充每行像素,以使宽度为4的倍数。因此,

我正在尝试从头开始制作位图。我有一个已知大小的RGB值的字节数组,我想生成一个HBITMAP

为了进一步澄清,我使用的字节数组纯粹是RGB值

我已确保所有变量都已设置且正确,我相信问题与lpvBits有关。在过去的几天里,我一直在为此做大量的研究,但我找不到任何对我有意义的东西

出于测试目的,宽度=6,高度=1

代码:


CreateBitmap的第三个参数应该是3,而不是1。有三种颜色平面:红色、绿色和蓝色


此外,如果将高度设置为大于1的任何值,则需要用零填充每行像素,以使宽度为4的倍数。因此,对于6x2图像,在为第一行保存6*3字节后,您需要保存两个零字节以使行的长度为20字节。

您需要正确地对数组进行dword对齐,以便每行是4字节的偶数倍,然后在填充数组时跳过这些字节:

HBITMAP RayTracing::getBitmap(void)
{
    BYTE * bytes = getPixels();
    HBITMAP hBMP = CreateBitmap(width, height, 1, 24, bytes);
    delete[] bytes;
    return hBMP;
}

BYTE * RayTracing::getPixels(void)
{
    Vec3 * vecs = display.getPixels(); // <-- don't forget to free if needed
    int linesize = ((3 * width) + 3) & ~3; // <- 24bit pixels, width number of pixels, rounded to nearest dword boundary
    BYTE * bytes = new BYTE[linesize * height];
    for (unsigned int y = 0; y < height; y++)
    {
        BYTE *line = &bytes[linesize*y];
        Vec3 *vec = &vecs[width*y];
        for (unsigned int x = 0; x < width; x++)
        {
            *line++ = static_cast<BYTE>(vec->x);
            *line++ = static_cast<BYTE>(vec->y);
            *line++ = static_cast<BYTE>(vec->z);
            ++vec;
        }
    }
    return bytes;
}

那么,你预计会发生什么?实际发生了什么?我正在尝试显示HBITMAP,但没有显示任何内容,也没有错误。你是否对齐了扫描线@重复数据消除器我很难理解word对齐我的原始数据意味着什么pixels@MichaelMitchell:为每行像素分配的空间必须是2字节的偶数倍。您正在创建一个24位位图。假设宽度为1。每个扫描线需要3个字节的像素数据和1个焊盘字节,因此必须为阵列分配3+1*高度字节。如果宽度为2,则每个扫描行需要6个字节,这是对齐的,因此数组需要6*个高度字节,依此类推。在分配数组时,将宽度乘以位/8,然后四舍五入到2的下一个最高倍数,并确保在用像素填充数组时考虑填充。我不确定这一点。我相信它仍然应该是一个。此外,如果我将其更改为3而不是1,则会出现运行时错误。我检查了Google,它看起来像CreateBitmap是一个非常旧的函数,应该只用于单色位图。改为使用CreateDIBSection。1是正确的值-检查文档中的BitMapInfo标头目标设备的平面数。此值必须设置为1。每个扫描行的宽度需要对齐,即使高度为1。不要选中Google,请选中。这不仅仅是因为CreateBitmap太旧,无法创建颜色位图,而是因为颜色匹配很难。CreateCompatibleBitmap和CreateDIBSection使它稍微容易一些。
HBITMAP RayTracing::getBitmap(void)
{
    BYTE * bytes = getPixels();
    HBITMAP hBMP = CreateBitmap(width, height, 1, 24, bytes);
    delete[] bytes;
    return hBMP;
}

BYTE * RayTracing::getPixels(void)
{
    Vec3 * vecs = display.getPixels(); // <-- don't forget to free if needed
    int linesize = ((3 * width) + 3) & ~3; // <- 24bit pixels, width number of pixels, rounded to nearest dword boundary
    BYTE * bytes = new BYTE[linesize * height];
    for (unsigned int y = 0; y < height; y++)
    {
        BYTE *line = &bytes[linesize*y];
        Vec3 *vec = &vecs[width*y];
        for (unsigned int x = 0; x < width; x++)
        {
            *line++ = static_cast<BYTE>(vec->x);
            *line++ = static_cast<BYTE>(vec->y);
            *line++ = static_cast<BYTE>(vec->z);
            ++vec;
        }
    }
    return bytes;
}