Jump to content

GDIPlus alpha issue


Go to solution Solved by genius257,

Recommended Posts

Posted

Good day,

 

I'm a bit in a pickle.

I'm trying to repaint a Graphics object area with 100% alpha color over an already painted area. Basically, the intent is to "clear" the area.

I can do it with the _GDIPlus_GraphicsClear function, I know. But, there are a few things to consider.

  1. My goal is to use animations.
  2. The working area is large, my dimensions are 1920x1080, full screen so to speak.
  3. With such a large area to clear with _GDIPlus_GraphicsClear in each frame, there are screen flickerings and it takes more time,  than just to repaint the neccesary small area. Already tried that.
  4. Repainting the previous area with background color and then painting the next area is also not quite an option as the background will be dynamic (moving image). This would require reading all the pixel colors of the previous area of the background at that instance, adding extra delay per frame.
  5. I have been experimenting with "layers", bitmaps created with _GDIPlus_BitmapCreateFromScan0, using 32bpp plus alpha and filling each with specific content and drawing them to a final bitmap as the final frame and then to the window Graphics object. This removed any flickering from doing one thing at a time and the speed is also reasonable. But, repainting with full alpha also does not work. And clearing the Graphics object, basically adds a delay as with the main window Graphics object.

 

Repainting with alpha just "paints over" the previous color instead completely changing the pixel.

 

So, my question is: Is there a way to change a solid color pixel with just alpha, and so to turn it to the original Graphics object pixel? Just so it looks like default, before doing any painting.

 

Here's a sample code of the issue.

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

Local $Gui = GUICreate("",200,200)

GUISetState()

Local $WindowGraphics = _GDIPlus_GraphicsCreateFromHWND($Gui)

Local $Brush = _GDIPlus_BrushCreateSolid(0xFF00FF00) ; Green

_GDIPlus_GraphicsFillRect($WindowGraphics,0,0,200,200,$Brush)

_GDIPlus_BrushSetSolidColor($Brush,0x800000FF) ; Blue, 50% alpha, mixes with green

_GDIPlus_GraphicsFillRect($WindowGraphics,0,0,200,200,$Brush)

_GDIPlus_BrushSetSolidColor($Brush,0x00000000) ; Total alpha, no effect

_GDIPlus_GraphicsFillRect($WindowGraphics,0,0,200,200,$Brush)

Local $Msg

While 1

    $Msg = GUIGetMsg()
    If $Msg = $GUI_EVENT_CLOSE Then ExitLoop

WEnd

GUIDelete()

 

Can it be done using other UDF's, like WinAPI? GDIPlus encoders? DLL's? Some kind of GUI style? Or maybe some kind of hack into the Graphics object?

 

Posted

What about painting the rectangular region in white opaque color and the drawing that same region with the background color? If you paint with the white brush and then paint with original transparent brush you will get the original color.

  • Solution
Posted

Hi @Archaic.

So I'm not 100% sure i get what you need.

First of all, your sample code does not work, you are missing _GDIPlus_Startup at the very least.

To clear the window graphics between frames with alpha content, you need to have a opaque color as the background. You can match the parent background-color, if possible.

To mostly avoid the flickering, you need double buffering, like you mention with a in memory bitmap from _GDIPlus_BitmapCreateFromScan0 and paint the result to the window graphics.
If i understand correctly you need to clear the in memory bitmap between frames, but _GDIPlus_GraphicsClear is too slow? If so you could always try changing CompositingMode with _GDIPlus_GraphicsSetCompositingMode with $GDIP_COMPOSITINGMODESOURCECOPY, draw your alpha color and flip back, but I think that is slower than using clear.

GDI+ is not great for big images updating quick, so depending on your need for speed, you might need openGL, Direct2D/3D or something else that is GPU accelerated.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...