using StretchDIBits() can i draw transparent and semitransparent?

using StretchDIBits() function, can i draw it without a color(backcolor transparent) and semi-transparent(opacy)?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void New(unsigned int SizeWidth, unsigned int SizeHeight, COLORREF BackColor=RGB(0,0,0))
        {
            int BufferSize = SizeWidth * SizeHeight * sizeof(unsigned int);

            if(BufferMemory) VirtualFree(BufferMemory, 0,MEM_RELEASE);
            BufferMemory = VirtualAlloc(0, BufferSize,MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
            Pixels =static_cast<unsigned int *> (BufferMemory);
            std::fill(Pixels, Pixels + SizeWidth * SizeHeight, BackColor);

            Width = SizeWidth;
            Height = SizeHeight;
            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;
        }
void Draw(HDC Destination, int PosY, int PosX)
        {
            if(BufferMemory)
            {
                StretchDIBits(Destination, PosX, PosY, Width, Height, 0,0, Width, Height,Pixels, &BitInfo,DIB_RGB_COLORS, SRCCOPY );
                
            }

        }
Last edited on
if everything is set up correctly and using transparency, yes.
the blts don't care. Its the canvas ... where you create compatible bmp or get a DC or whatever you are doing that needs to be alpha enabled.
Last edited on
how can i add or change the alpha?
it probably already has it, but check stuff like
BitInfo.bmiHeader.biCompression = BI_RGB;
you may be turning it off there, maybe it wants an A on that...
or DIB_RGB_COLORS
Last edited on
StretchDIBits() does not support alpha transparency. Never has, and probably never will.

Er, here is what recommendation I quickly googled: https://stackoverflow.com/a/55070258/2706707
What DIBits() functions can use alpha value?
At this point, not sure. Ive only done really simple transparency, and about all I can say is that reading up on it, bitblt accidentally works and if you want more than that, you have to use gdiplus.
Using Math, how combine the source and destination pixels with alpha value?
At least now i can use alpha.. the transparent is just not draw a pixel color ;)
better look it up. I can make a guess, but there are probably details that require reading a bit more.
i only found these:
RR = SR × SA + DR × (1 − SA)
RG = SG × SA + DG × (1 − SA)
RB = SB × SA + DB × (1 − SA)
on here: https://ciechanow.ski/alpha-compositing/
i will try it... thanks
so i did these function now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
COLORREF AlphaBlendPixels(COLORREF SourcePixel, COLORREF DestinationPixel, BYTE AlphaValue)
{
    //Get Source RGB Colors:
    BYTE SR = GetRValue(SourcePixel);
    BYTE SG = GetGValue(SourcePixel);
    BYTE SB = GetBValue(SourcePixel);

    //Get Destination RGB Colors:
    BYTE DR = GetRValue(DestinationPixel);
    BYTE DG = GetGValue(DestinationPixel);
    BYTE DB = GetBValue(DestinationPixel);
    
    //Combine the 2 bit pixels with Alpha Value:
    BYTE RR = SR * AlphaValue + DR * (1-AlphaValue);
    BYTE RG = SG * AlphaValue + DG * (1-AlphaValue);
    BYTE RB = SB * AlphaValue + DB * (1-AlphaValue);

    return RGB(RR,RG,RB);
}

i'm confused: why '-1'?
Last edited on
good luck. It seems likely that you want SA = A/255 as a percent, and 1-(A/255) (the opposite percent, such that 25% and 75% are 100%.. 1.0 is 100% ..)
(I didn't read it, but just warning you that A here isnt 0-255 in case they didn't tell you).

it also seems likely that there is a more efficient way to do that math, but see if it works first
Last edited on
theres so many code.. but i choose the used class Bitmap functions:
1
2
3
4
5
6
7
8
9
10
11
void Draw(Bitmap &BitPixels, int PosY, int PosX, COLORREF TransparentColor =0, BYTE AlphaBlendValue=0)
        {
            for(unsigned int Y = PosY, SourceY =0; Y < (Height+PosY); Y++, SourceY++)
            {
                for (unsigned int X= PosX, SourceX =0; X<(Width+PosX); X++, SourceX++)
                {
                    //if(TransparentColor!=0 && BitPixels.Pixels[Y*BitPixels.Width + X] == TransparentColor) continue;
                    BitPixels.Pixels[Y*BitPixels.Width + X] = AlphaBlendPixels ((COLORREF)Pixels[SourceY*Width + SourceX],(COLORREF) BitPixels.Pixels[Y*BitPixels.Width + X], AlphaBlendValue);
                }
            }
        }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
COLORREF AlphaBlendPixels(COLORREF SourcePixel, COLORREF DestinationPixel, BYTE AlphaValue)
{
    //Get Source RGB Colors:
    BYTE SR = GetRValue(SourcePixel);
    BYTE SG = GetGValue(SourcePixel);
    BYTE SB = GetBValue(SourcePixel);

    //Get Destination RGB Colors:
    BYTE DR = GetRValue(DestinationPixel);
    BYTE DG = GetGValue(DestinationPixel);
    BYTE DB = GetBValue(DestinationPixel);

    //Combine the 2 bit pixels with Alpha Value:
    BYTE RR = SR * AlphaValue + DR * (1-AlphaValue / 255);
    BYTE RG = SG * AlphaValue + DG * (1-AlphaValue / 255);
    BYTE RB = SB * AlphaValue + DB * (1-AlphaValue / 255);

    return RGB(RR,RG,RB);
}

now the main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{


    HWND HWNDConsoleWindow = GetConsoleWindow();
    HDC HDCConsoleWindow = GetDC(HWNDConsoleWindow);

    Bitmap Bit(500,500,RGB(255 ,0,0));
    Bitmap Bit2(100,100,RGB(0,0,255));
    do
    {
        //the Bit2 is just like a rectangle and is drawed on Bit:
        Bit2.Draw(Bit,20,20,0,250);
        //Draw the Bit on Window:
        Bit.Draw(HDCConsoleWindow,100,100);

    }while(!GetAsyncKeyState(VK_ESCAPE));
    return 0;
}

but i see 2 problems:
1 - the AlphaBlend() math seems wrong(i don't see the transparency correctly);
https://imgur.com/dFnhPnw

2 - why i get the flicker when i draw 'Bit' on HDC Window? too much for CPU?
Last edited on
Topic archived. No new replies allowed.