how use BITMAPINFO? why is BGR() instead RGB()?

heres how i use BITMAPINFO:
1
2
3
4
5
6
7
8
BitInfo.bmiHeader.biSize = sizeof(BitInfo.bmiHeader);
            BitInfo.bmiHeader.biWidth = Width;
            BitInfo.bmiHeader.biHeight = -Height;
            BitInfo.bmiHeader.biPlanes = 1;
            BitInfo.bmiHeader.biBitCount = 32;
            BitInfo.bmiHeader.biCompression = BI_RGB;~
//on draw:
StretchDIBits(Destination, PosX, PosY, Width, Height, 0,0, Width, Height,Pixels, &BitInfo,DIB_RGB_COLORS, SRCCOPY );

why is BGR() instead RGB()?
Last edited on
Could you clarify your question. I don't see BGR mentioned anywhere in your code.
Last edited on
> why is BGR() instead RGB()?
And in an alternate reality, someone's asking
why is RGB() instead BGR()?

Plus there's the whole "do you read left to right or right to left" when looking at bytes in a word.
Which depends on whether you're looking at big-endian or little-endian data.

My guess that you mean that the rgb values are stored as bgr in the output buffer. The reason for this is most likely that the buffer is an array of COLORREF which is a DWORD. See:

https://docs.microsoft.com/en-us/windows/win32/gdi/colorref
BITMAPINFO is part of Windows API and described by Microsoft: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfo

Why Microsoft chose their API to have those things? I don't need to know.
I think it is simply byte-order issue from using int as their pixel / color storage.
thanks for that information to all.
but can i change the code for use RGB() instead BGR()?
Can you respond to Peter's request? I do not see "BGR()" in your code.
But anyway, as the others mentioned, it seems like Windows DIB bitmaps are BGR (0x00BBGGRR), and you can't change this.
Last edited on
Pixels[PosY*Width + PosX] = RGB(255,0,0);
i will get Blue and not Red.
The COLORREF data is expected to be 0x00BBGGRR. If the order of the parameters is important to you, you could do something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <iomanip>

using COLORREF = unsigned int; // assumes 32-bit int

COLORREF RGB_to_COLORREF(unsigned int r, unsigned int g, unsigned int b)
{
    return COLORREF(
         (r & 0xFF) |
        ((g & 0xFF) << 8) |
        ((b & 0xFF) << 16));
}

int main()
{
    std::cout << "0x00BBGGRR\n";
    std::cout << "0x00" << std::hex << RGB_to_COLORREF(0x11, 0x22, 0x33) << '\n';
}

0x00BBGGRR
0x00332211
Last edited on
microsoft has _byteswap*** family of functions. If I am not mistaken, this lets you, even in 64 bit, tap the CPUs bswap command, to byte-order flip a register.
the int from rgb macro can be flipped and if needed, shifted then assigned.
If you need to do that a lot, make a BGR() function to mirror the RGB() macro.

If you do not need to call RGB at all, doing it directly is faster than doing it and then flipping it, even with the register command.

OR, you could do it directly:
unsigned char * realpixels = (unsigned char *)Pixels;
realpixels[PosY*Width*3+PosX] = 255;
realpixels[PosY*Width*3+PosX+1] = 0;
realpixels[PosY*Width*3+PosX+2] = 0;
and you need that 4th byte, which is either position 0 or position 3.
If its position 0, fix the above with a +1 for the RGB info and do whatever to the [0] byte.
if its position 3, leave above alone and do whatever to [..+3] byte.

be sure to test it... use it to set all the pixels to red, then green, then blue and if all 3 colors work, you are loading the right bytes.
Last edited on
Topic archived. No new replies allowed.