Jump to content

GDI+ Transparency Mask


Andreik
 Share

Recommended Posts

As a request in this thread I wrote a small function to add a transparency mask to a bitmap. I post it here with an example, maybe someone else will need it. The function works with both 32/64 bit versions of AutoIt.

#AutoIt3Wrapper_UseX64=y
#include <GDIPlus.au3>
#include <Memory.au3>

$hMain = GUICreate('Transparency mask blending', 720, 400)
$cPic = GUICtrlCreatePic('', 0, 0, 720, 400)
GUISetState(@SW_SHOW, $hMain)

_GDIPlus_Startup()
$hDraw = _GDIPlus_BitmapCreateFromScan0(720, 400)
$hBackground = _GDIPlus_ImageLoadFromFile('background.png')
$hTree = _GDIPlus_ImageLoadFromFile('tree.png')
$hMask = _GDIPlus_ImageLoadFromFile('mask.png')
$hGraphics = _GDIPlus_ImageGetGraphicsContext($hDraw)
$aDim = _GDIPlus_ImageGetDimension($hTree)

$DrawWithMask = False
AdlibRegister('Draw', 3000)
Draw()

Do
Until GUIGetMsg() =  -3 ; GUI_EVENT_CLOSE

_GDIPlus_BitmapDispose($hDraw)
_GDIPlus_ImageDispose($hBackground)
_GDIPlus_ImageDispose($hTree)
_GDIPlus_ImageDispose($hMask)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()

Func Draw()
    _GDIPlus_GraphicsClear($hGraphics)
    _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hBackground, 0, 0, 720, 400, 0, 0, 720, 400)
    If $DrawWithMask Then
        Local $hCloneTree = _GDIPlus_ImageClone($hTree)
        SetBitmapMask($hCloneTree, $hMask)
        _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hCloneTree, 0, 0, $aDim[0], $aDim[1], 550, 200, $aDim[0], $aDim[1])
        _GDIPlus_ImageDispose($hCloneTree)
    Else
        _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hTree, 0, 0, $aDim[0], $aDim[1], 550, 200, $aDim[0], $aDim[1])
    EndIf
    BitmapToCtrl($hDraw, $cPic)
    $DrawWithMask = Not $DrawWithMask
EndFunc

Func SetBitmapMask($hBitmap, $hMask)
    Local $aDim1 = _GDIPlus_ImageGetDimension($hBitmap)
    Local $aDim2 = _GDIPlus_ImageGetDimension($hMask)
    If $aDim1[0] <> $aDim2[0] Or $aDim1[1] <> $aDim1[1] Then Return SetError(1, 0, Null)
    Local $tBitmap = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $aDim1[0], $aDim1[1], BitOR($GDIP_ILMWRITE, $GDIP_ILMREAD), $GDIP_PXF32ARGB)
    Local $tMask = _GDIPlus_BitmapLockBits($hMask, 0, 0, $aDim2[0], $aDim2[1], BitOR($GDIP_ILMWRITE, $GDIP_ILMREAD), $GDIP_PXF32ARGB)
    If @AutoItX64 Then
        Local $sCode = '0x56534C89C6BBFFFFFF00AD25000000FF211A09024883C204E2F05B5EC3'
    Else
        Local $sCode = '0x8B4C24048B7C24088B74240CBBFFFFFF00AD25000000FF211F090783C704E2F1C20C00'
    EndIf
    Local $dCode = Binary($sCode)
    Local $iCode = BinaryLen($dCode)
    Local $pCode = _MemVirtualAlloc(0, $iCode, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    Local $tCode = DllStructCreate('byte Code[' & $iCode & ']', $pCode)
    $tCode.Code = $dCode
    Local $aCall = DllCallAddress('int', DllStructGetPtr($tCode), 'int', $aDim1[0] * $aDim1[1], 'ptr', $tBitmap.Scan0, 'ptr', $tMask.Scan0)
    _MemVirtualFree($pCode, $iCode, $MEM_DECOMMIT)
    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmap)
    _GDIPlus_BitmapUnlockBits($hMask, $tMask)
    Return $aDim1
EndFunc

Func BitmapToCtrl($hBitmap, $cCtrl)
    Local Static $STM_SETIMAGE = 0x0172
    $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($cCtrl, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBITMAP))
    _WinAPI_DeleteObject($hHBITMAP)
EndFunc

Resources used in this example can be downloaded at the link below (sorry for external link, my attachement quota is 100%). Credits for graphics resources goes to https://itch.io.

 

 

Transparency Mask.zip

Edited by Andreik
Freed some space so I attached the resources here.

When the words fail... music speaks.

Link to comment
Share on other sites

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
 Share

×
×
  • Create New...