简体   繁体   中英

c++ trouble with making a bitmap from scratch

I am trying to make a bitmap from scratch. I have a BYTE array (with known size) of RGB values and I would like to generate an HBITMAP.

For further clarification, the array of bytes I am working with is purely RGB values.

I have made sure that all variables are set and proper, and I believe that the issue has to do with lpvBits . I have been doing as much research for this in the past few days I have been unable to find anything that makes sense to me.

For testing purposes the width = 6 and height = 1

Code:

HBITMAP RayTracing::getBitmap(void){
    BYTE * bytes = getPixels();
    void * lpvBits = (void *)bytes;
    HBITMAP hBMP = CreateBitmap(width, height, 1, 24, lpvBits);
    return hBMP;
}
BYTE * RayTracing::getPixels(void){
    Vec3 * vecs = display.getPixels();
    BYTE * bytes;
    bytes = new BYTE[(3 * width * height)];
    for (unsigned int i = 0; i < (width * height); i++){
        *bytes = static_cast<BYTE>(vecs->x);
        bytes++;
        *bytes = static_cast<BYTE>(vecs->y);
        bytes++;
        *bytes = static_cast<BYTE>(vecs->z);
        bytes++;
        vecs++;
    }
    return bytes;
}

You need to properly dword-align your array so each line is an even multiple of 4 bytes, and then skip those bytes when filling the array:

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;
}

The third parameter of CreateBitmap should be 3, not 1. There are three color planes: Red, Green, and Blue.

Also, if you set the height to anything greater than one, you'll need to pad each row of pixels with zeroes to make the width a multiple of 4. So for a 6x2 image, after saving the 6*3 bytes for the first row, you'd need to save two zero bytes to make the row 20 bytes long.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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