Jump to content

_GDIPlus_BitmapCreateBitmapWithAlpha()


Recommended Posts

This small function allows you to add an alpha channel (mask) to the specified GDI+ bitmap (see screenshots). Source bitmap and mask may be of any color depth. The output bitmap is always 32 bits-per-pixel with alpha channel. Optionally, the alpha channel may be generated from any channel of the specified mask (1 - Red, 2 - Green, 3 - Blue, or 0 - Alpha). The example below is written for Autoit 3.3.12.0.

 

post_img_094.pngpost_img_095.pngpost_img_096.png

#Include <GDIPlus.au3>

If StringRegExpReplace(@AutoItVersion, '(?<!\d)(\d)(?!\d)', '0\1') < '03.03.12.00' Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

_GDIPlus_Startup()
$hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Image.png')
$hAlpha = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Alpha.png')
$hResult = _GDIPlus_BitmapCreateBitmapWithAlpha($hBitmap, $hAlpha, 1)
_GDIPlus_ImageSaveToFile($hResult, @ScriptDir & '\Image+Alpha.png')
_GDIPlus_BitmapDispose($hResult)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_BitmapDispose($hAlpha)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapCreateBitmapWithAlpha($hBitmap, $hAlpha, $iChannel = 0)

    Local $hGraphics, $hBmp[2], $bProc, $tProc, $pProc, $Size1, $Size2, $Lenght, $Result
    Local $tData[2] = [$GDIP_ILMWRITE, $GDIP_ILMREAD]

    $Size1 = DllCall($__g_hGDIPDll, 'uint', 'GdipGetImageDimension', 'handle', $hBitmap, 'float*', 0, 'float*', 0)
    If (@Error) Or ($Size1[0]) Then
        Return 0
    EndIf
    $Size2 = DllCall($__g_hGDIPDll, 'uint', 'GdipGetImageDimension', 'handle', $hAlpha, 'float*', 0, 'float*', 0)
    If (@Error) Or ($Size2[0]) Then
        Return 0
    EndIf
    $hBmp[0] = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $Size1[2], $Size1[3], $GDIP_PXF32ARGB)
    If ($Size1[2] = $Size2[2]) And ($Size1[3] = $Size2[3]) Then
        $hBmp[1] = $hAlpha
    Else
        $hBmp[1] = _GDIPlus_BitmapCreateFromScan0($Size1[2], $Size1[3], $GDIP_PXF32ARGB)
        $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp[1])
        _GDIPlus_GraphicsClear($hGraphics, 0)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hAlpha, 0, 0, $Size1[2], $Size1[3])
        _GDIPlus_GraphicsDispose($hGraphics)
    EndIf
    If ($iChannel < 0) Or ($iChannel > 3) Then
        $iChannel = 0
    EndIf
    For $i = 0 To 1
        $tData[$i] = _GDIPlus_BitmapLockBits($hBmp[$i], 0, 0, $Size1[2], $Size1[3], $tData[$i], $GDIP_PXF32ARGB)
    Next
    If @AutoItX64 Then
        $bProc = Binary('0x48894C240848895424104C894424184C894C24205541574831C0505050504883EC2848837C24600074054831C0EB0748C7C0010000004821C00F858100000048837C24680074054831C0EB0748C7C0010000004821C07555837C24700074054831C0EB0748C7C0010000004821C0752A4C637C24784D21FF7C0D4C637C24784983FF037F02EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C0740B4831C04863C0E9950000004C8B7C24604983C7034C897C24284C8B7C246848634424784929C74983C7034C897C243048C7442438000000004C637C247049FFCF4C3B7C24387C4A488B6C24284C0FB67D00488B6C2430480FB645004C0FAFF84C89F848C7C1FF000000489948F7F94989C74C89F850488B6C24305888450048834424280448834424300448FF44243871A748C7C0010000004863C0EB034831C04883C448415F5DC3')
    Else
        $bProc = Binary('0x555331C0505050837C241800740431C0EB05B80100000021C07568837C241C00740431C0EB05B80100000021C07545837C242000740431C0EB05B80100000021C075228B5C242421DB7C0B8B5C242483FB037F02EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C0740431C0EB6B8B5C241883C303891C248B5C241C2B5C242483C303895C2404C7442408000000008B5C24204B3B5C24087C368B2C240FB65D008B6C24040FB645000FAFD889D8B9FF00000099F7F989C3538B6C240458884500830424048344240404FF44240871BFB801000000EB0231C083C40C5B5DC21000')
    EndIf
    $Length = BinaryLen($bProc)
    $pProc = DllCall('kernel32.dll', 'ptr', 'VirtualAlloc', 'ptr', 0, 'ulong_ptr', $Length, 'dword', 0x1000, 'dword', 0x0040)
    $tProc = DllStructCreate('byte[' & $Length & ']', $pProc[0])
    DllStructSetData($tProc, 1, $bProc)
    $Result = DllCallAddress('uint', $pProc[0], 'ptr', $tData[0].Scan0, 'ptr', $tData[1].Scan0, 'uint', $Size1[2] * $Size1[3], 'uint', $iChannel)
    If Not $Result[0] Then
        ; Nothing
    EndIf
    DllCall('kernel32.dll', 'int', 'VirtualFree', 'ptr', $pProc[0], 'ulong_ptr', 0, 'dword', 0x4000)
    For $i = 0 To 1
        _GDIPlus_BitmapUnlockBits($hBmp[$i], $tData[$i])
    Next
    If $hBmp[1] <> $hAlpha Then
        _GDIPlus_BitmapDispose($hBmp[1])
    EndIf
    Return $hBmp[0]
EndFunc   ;==>_GDIPlus_BitmapCreateBitmapWithAlpha

Function + Example

Previous downloads: 47

GDIPlus_BitmapCreateBitmapWithAlpha.zip

Edited by Yashied
Link to post
Share on other sites

If @AutoItVersion <> '3.3.12.0' Then

?? small typo ??

Edited by mLipok

Signature beginning:
Please remember: "AutoIt".....  Wondering who uses AutoIt and what it can be used for ?
* GHAPI UDF - modest beginning - communication with GitHub REST API Forum Rules *
Include Dependency Tree (Tool for analyzing script relations)
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) *

PDF Related:How to get reference to PDF object embeded in IE *

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2021-03-17

Link to post
Share on other sites

....

;~If @AutoItVersion <> '3.3.12.0' Then
;~  MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
;~EndIf

....

 

this should do: (from >here)

; use 3 digits for each portion of the version without dots
; (Leading zeros are not needed)
; 3.3.12.0 -> 003.003.012.000 -> 3003012000

If _AutoItVersion() < 3003012000 Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

Func _AutoItVersion()
    Local $aAutoItV = StringSplit(@AutoItVersion, ".", 2)
    Return StringFormat("%03i%03i%03i%03i", $aAutoItV[0], $aAutoItV[1], $aAutoItV[2], $aAutoItV[3])
EndFunc   ;==>_AutoItVersion

p.s.

sorry for the little offtopic hijacking

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to post
Share on other sites

Excellent code. I too would like to "study" the ASM code. -_0

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to post
Share on other sites

this should do: (from >here)

; use 3 digits for each portion of the version without dots
; (Leading zeros are not needed)
; 3.3.12.0 -> 003.003.012.000 -> 3003012000

If _AutoItVersion() < 3003012000 Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

Func _AutoItVersion()
    Local $aAutoItV = StringSplit(@AutoItVersion, ".", 2)
    Return StringFormat("%03i%03i%03i%03i", $aAutoItV[0], $aAutoItV[1], $aAutoItV[2], $aAutoItV[3])
EndFunc   ;==>_AutoItVersion

p.s.

sorry for the little offtopic hijacking

 

I was just wondering how to solve the "task", which @Yashied want to use.

 

EDIT:

My example.

Edited by mLipok

Signature beginning:
Please remember: "AutoIt".....  Wondering who uses AutoIt and what it can be used for ?
* GHAPI UDF - modest beginning - communication with GitHub REST API Forum Rules *
Include Dependency Tree (Tool for analyzing script relations)
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) *

PDF Related:How to get reference to PDF object embeded in IE *

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2021-03-17

Link to post
Share on other sites

I too would like to "study" the ASM code.

I didn't write ASM code, I wrote and compiled DLL in other language and then retrieved a binary code of appropriate function. In AutoIt this function looks like this, but in AutoIt it takes a lot of time.

Func _AddAlpha($pBits1, $pBits2, $iWidth, $iHeght, $iChannel)
    If (Not $pBits1) Or (Not $pBits2) Or ($iChannel < 0) Or ($iChannel > 3) Then Return 0
    Local $iOffset = 3 - $iChannel
    For $i = 0 To $iWidth * $iHeght * 4 - 4 Step 4
        Local $tData1 = DllStructCreate('byte', $pBits1 + $i + 3)
        Local $tData2 = DllStructCreate('byte', $pBits2 + $i + $iOffset)
        DllStructSetData($tData1, 1, DllStructGetData($tData1, 1) * DllStructGetData($tData2, 1) / 255)
    Next
    Return 1
EndFunc

Retrieving binary code:

#Include <WinAPIEx.au3>

$File = FileOpenDialog('Select File', @ScriptDir, 'Libraries (*.dll)|All Files (*.*)', 1 + 2)
If Not $File Then
    Exit
EndIf
$hModule = _WinAPI_LoadLibrary($File)
If Not $hModule Then
    MsgBox(0x00040010, 'Error', 'Unable to load ' & StringRegExpReplace($File, '^.*\\', '') & '.')
    Exit
EndIf
Do
    $pFirst = _WinAPI_GetProcAddress($hModule, 'First')
    If @Error Then
        MsgBox(0x00040010, 'Error', '"First()" procedure not found.')
        ExitLoop
    EndIf
    $pLast = _WinAPI_GetProcAddress($hModule, 'Last')
    If @Error Then
        MsgBox(0x00040010, 'Error', '"Last()" procedure not found.')
        ExitLoop
    EndIf
    $tData = DllStructCreate('byte[' & Number($pLast - $pFirst) & ']', $pFirst)
    If @Error Then
        MsgBox(0x00040010, 'Error', 'Invalid addresses.')
        ExitLoop
    EndIf
    $Code = String(DllStructGetData($tData, 1))
    ConsoleWrite($Code & @CR)
    ClipPut($Code)
Until 1
_WinAPI_FreeLibrary($hModule)

Here Alpha.dll (x86) for example.

Edited by Yashied
Link to post
Share on other sites

Ah OK, thanks.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to post
Share on other sites

I've decided to experiment and wrote a version of this function by using threads (up to 4). Yes, it reduced the time to perform external function, but unfortunately most of the time consuming _GDIPlus... function. Nevertheless, if anyone is interested here is a function.

 

#Include <GDIPlus.au3>

If StringRegExpReplace(@AutoItVersion, '(?<!\d)(\d)(?!\d)', '0\1') < '03.03.12.00' Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

_GDIPlus_Startup()
$hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Image.png')
$hAlpha = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Alpha.png')
$hResult = _GDIPlus_BitmapCreateBitmapWithAlpha($hBitmap, $hAlpha, 1)
_GDIPlus_ImageSaveToFile($hResult, @ScriptDir & '\Image+Alpha.png')
_GDIPlus_BitmapDispose($hResult)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_BitmapDispose($hAlpha)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapCreateBitmapWithAlpha($hBitmap, $hAlpha, $iChannel = 0)

    Local $hGraphics, $hBmp[2], $hThread, $iThread, $tParams, $bProc, $tProc, $pProc, $aSize1, $aSize2, $aLength, $iLength, $iOffset, $aResult
    Local $tData[2] = [$GDIP_ILMWRITE, $GDIP_ILMREAD]

    $aSize1 = DllCall($__g_hGDIPDll, 'uint', 'GdipGetImageDimension', 'handle', $hBitmap, 'float*', 0, 'float*', 0)
    If (@Error) Or ($aSize1[0]) Then
        Return 0
    EndIf
    $aSize2 = DllCall($__g_hGDIPDll, 'uint', 'GdipGetImageDimension', 'handle', $hAlpha, 'float*', 0, 'float*', 0)
    If (@Error) Or ($aSize2[0]) Then
        Return 0
    EndIf
    $hBmp[0] = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $aSize1[2], $aSize1[3], $GDIP_PXF32ARGB)
    If ($aSize1[2] = $aSize2[2]) And ($aSize1[3] = $aSize2[3]) Then
        $hBmp[1] = $hAlpha
    Else
        $hBmp[1] = _GDIPlus_BitmapCreateFromScan0($aSize1[2], $aSize1[3], $GDIP_PXF32ARGB)
        $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp[1])
        _GDIPlus_GraphicsClear($hGraphics, 0)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hAlpha, 0, 0, $aSize1[2], $aSize1[3])
        _GDIPlus_GraphicsDispose($hGraphics)
    EndIf
    If ($iChannel < 0) Or ($iChannel > 3) Then
        $iChannel = 0
    EndIf
    For $i = 0 To 1
        $tData[$i] = _GDIPlus_BitmapLockBits($hBmp[$i], 0, 0, $aSize1[2], $aSize1[3], $tData[$i], $GDIP_PXF32ARGB)
    Next
    If @AutoItX64 Then
        $bProc = Binary('0x48894C24085541574831C0505050504883EC28488B6C246048837D000074054831C0EB0748C7C0010000004821C00F8591000000488B6C246048837D080074054831C0EB0748C7C0010000004821C07561488B6C2460837D100074054831C0EB0748C7C0010000004821C07532488B6C24604C637D144D21FF7C11488B6C24604C637D144983FF037F02EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C0740B4831C04863C0E9A5000000488B6C24604C8B7D004983C7034C897C2428488B6C24604C8B7D08488B6C2460486345144929C74983C7034C897C243048C744243800000000488B6C24604C637D1049FFCF4C3B7C24387C4A488B6C24284C0FB67D00488B6C2430480FB645004C0FAFF84C89F848C7C1FF000000489948F7F94989C74C89F850488B6C24305888450048834424280448834424300448FF44243871A348C7C0010000004863C0EB034831C04883C448415F5DC3')
    Else
        $bProc = Binary('0x555331C05050508B6C2418837D0000740431C0EB05B80100000021C075748B6C2418837D0400740431C0EB05B80100000021C0754E8B6C2418837D0800740431C0EB05B80100000021C075288B6C24188B5D0C21DB7C0E8B6C24188B5D0C83FB037F02EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C0740431C0EB778B6C24188B5D0083C303891C248B6C24188B5D048B6C24182B5D0C83C303895C2404C7442408000000008B6C24188B5D084B3B5C24087C368B2C240FB65D008B6C24040FB645000FAFD889D8B9FF00000099F7F989C3538B6C240458884500830424048344240404FF44240871BCB801000000EB0231C083C40C5B5DC20400')
    EndIf
    $iLength = BinaryLen($bProc)
    $pProc = DllCall('kernel32.dll', 'ptr', 'VirtualAlloc', 'ptr', 0, 'ulong_ptr', $iLength, 'dword', 0x1000, 'dword', 0x0040)
    $tProc = DllStructCreate('byte[' & $iLength & ']', $pProc[0])
    DllStructSetData($tProc, 1, $bProc)
    $iLength = $aSize1[2] * $aSize1[3]
    Select
        Case $iLength > 2 ^ 24
            $iThread = 4
        Case $iLength > 2 ^ 20
            $iThread = 2
        Case Else
            $iThread = 1
    EndSelect
    Dim $aLength[$iThread]
    Dim $tParams[$iThread]
    Dim $hThread[$iThread]
    If $iThread = 1 Then
        $aLength[0] = $iLength
    Else
        $aLength[0] = Floor($iLength / $iThread)
        $aLength[$iThread - 1] = $iLength - $aLength[0] * ($iThread - 1)
        For $i = 1 To $iThread - 2
            $aLength[$i] = $aLength[0]
        Next
    EndIf
    $iOffset = 0
    For $i = 0 To $iThread - 1
        $tParams[$i] = DllStructCreate('ptr;ptr;uint;uint')
        DllStructSetData($tParams[$i], 1, $tData[0].Scan0 + $iOffset)
        DllStructSetData($tParams[$i], 2, $tData[1].Scan0 + $iOffset)
        DllStructSetData($tParams[$i], 3, $aLength[$i])
        DllStructSetData($tParams[$i], 4, $iChannel)
        $iOffset+= 4 * $aLength[$i]
        $aResult = DllCall('kernel32.dll', 'handle', 'CreateThread', 'ptr', 0, 'dword_ptr', 0, 'ptr', $pProc[0], 'struct*', $tParams[$i], 'dword', 0, 'ptr', 0)
        If (Not @Error) And ($aResult[0]) Then
            $hThread[$i] = $aResult[0]
        Else
            $hThread[$i] = 0
        EndIf
    Next
    While 1
        $iLength = 0
        For $i = 0 To $iThread - 1
            If $hThread[$i] Then
                $aResult = DllCall('kernel32.dll', 'bool', 'GetExitCodeThread', 'handle', $hThread[$i], 'dword*', 0)
                If (@Error) Or (Not $aResult[0]) Or ($aResult[2] <> 259) Then
                    DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $hThread[$i])
                    $hThread[$i] = 0
                Else
                    $iLength += 1
                EndIf
            EndIf
        Next
        If Not $iLength Then
            ExitLoop
        EndIf
    WEnd
    $aResult = DllCall('kernel32.dll', 'int', 'VirtualFree', 'ptr', $pProc[0], 'ulong_ptr', 0, 'dword', 0x4000)
    If (@Error) Or (Not $aResult[0]) Then
        ; Nothing
    EndIf
    For $i = 0 To 1
        _GDIPlus_BitmapUnlockBits($hBmp[$i], $tData[$i])
    Next
    If $hBmp[1] <> $hAlpha Then
        _GDIPlus_BitmapDispose($hBmp[1])
    EndIf
    Return $hBmp[0]
EndFunc   ;==>_GDIPlus_BitmapCreateBitmapWithAlpha
Edited by Yashied
Link to post
Share on other sites
  • 1 month later...

I added an experimental ASM version:

 

#Include <GDIPlus.au3>

If StringRegExpReplace(@AutoItVersion, '(?<!\d)(\d)(?!\d)', '0\1') < '03.03.12.00' Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

If FileExists(@ScriptDir & '\Image+AlphaASM.png') Then FileDelete(@ScriptDir & '\Image+AlphaASM.png')
_GDIPlus_Startup()
$hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Image.png')
$hAlpha = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Alpha.png')
_GDIPlus_BitmapCreateBitmapWithAlphaASM($hBitmap, $hAlpha)
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & '\Image+AlphaASM.png')
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_BitmapDispose($hAlpha)
_GDIPlus_Shutdown()
ShellExecute(@ScriptDir & '\Image+AlphaASM.png')

Func _GDIPlus_BitmapCreateBitmapWithAlphaASM($hBitmap, $hBitmap_AlphaMask) ;coded by UEZ build 2015-02-26
    Local $fTimer_All = TimerInit()
    Local Const $iWidth = _GDIPlus_ImageGetWidth($hBitmap), $iHeight = _GDIPlus_ImageGetHeight($hBitmap)
    If _GDIPlus_ImageGetWidth($hBitmap_AlphaMask) <> $iWidth Or _GDIPlus_ImageGetHeight($hBitmap) <> $iHeight Then Return SetError(1, 0, 0)
    Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
    Local Const $pScan = $tBitmapData.Scan0
    Local Const $iStride = $tBitmapData.Stride
    Local Const $tPixelData = DllStructCreate("dword[" & (Abs($iStride * $iHeight)) & "]", $pScan)

    Local Const $tBitmapAlphaMaskData = _GDIPlus_BitmapLockBits($hBitmap_AlphaMask, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    Local Const $pScanAlpha = $tBitmapAlphaMaskData.Scan0
    Local Const $iStrideAlpha = $tBitmapAlphaMaskData.Stride
    Local Const $tPixelAlphaMaskData = DllStructCreate("dword[" & (Abs($iStrideAlpha * $iHeight)) & "]", $pScanAlpha)

    Local $fTimer_ASM = TimerInit()
    Local $tCodeBuffer = DllStructCreate("byte ASM[46]")
    $tCodeBuffer.ASM = "0x8B7424048B4C24088B7C240C8B0625FFFFFF008B1F81E30000FF00C1E30809D8890683C60483C70483E90177DFC3"
    DllCall("user32.dll", "ptr", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), _
                          "ptr", DllStructGetPtr($tPixelData), _
                          "int", $iWidth * $iHeight , _
                          "ptr", DllStructGetPtr($tPixelAlphaMaskData), "int",0)
    ConsoleWrite("ASM: " & TimerDiff($fTimer_ASM) & " ms." & @CRLF)

    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData)
    _GDIPlus_BitmapUnlockBits($hBitmap_AlphaMask, $tBitmapData)
    ConsoleWrite("Overall: " & TimerDiff($fTimer_All) & " ms." & @CRLF)
    Return 1
EndFunc

#cs ASM
      .data:0x00000000    8b742404        mov    esi,DWORD PTR [esp+0x4]  ;start address of the bitmap
      .data:0x00000004    8b4c2408        mov    ecx,DWORD PTR [esp+0x8]  ;number of pixel -> $iWidth * $iHeight
      .data:0x00000008    8b7c240c        mov    edi,DWORD PTR [esp+0xc]  ;start address of the alpha mask bitmap
      .data:0x0000000c
      .data:0x0000000c        loc_0000000c:
┏▶  .data:0x0000000c    8b06            mov    eax,DWORD PTR [esi]      ;get the pixel from the bitmap
┃     .data:0x0000000e    25ffffff00      and    eax,0xffffff             ;remove alpha channel
┃     .data:0x00000013    8b1f            mov    ebx,DWORD PTR [edi]      ;get the pixel from alpha mask bitmap
┃     .data:0x00000015    81e30000ff00    and    ebx,0xff0000             ;get red value only because r=g=b (greyscale). This will be our alpha channel
┃     .data:0x0000001b    c1e308          shl    ebx,0x8                  ;shift the value to the alpha channel place AArrggbb
┃     .data:0x0000001e    09d8            or     eax,ebx                  ;add the alpha channel value to the bitmap pixel
┃     .data:0x00000020    8906            mov    DWORD PTR [esi],eax      ;write the pixel to the bitmap -> should be a greyscaled color value
┃     .data:0x00000022    83c604          add    esi,0x4                  ;address next pixel: 3 Byte = 1 dword = 1 Pixel
┃     .data:0x00000025    83c704          add    edi,0x4                  ;address next pixel: 3 Byte = 1 dword = 1 Pixel
┃     .data:0x00000028    83e901          sub    ecx,0x1                  ;counter (next pixel)
┗     .data:0x0000002b    77df            ja     loc_0000000c             ;jump as long as counter is not zero
      .data:0x0000002d    c3              ret
 

My results for the images on op:

ASM: 0.196242006627889 ms.

Overall: 8.97499269224327 ms.

 

 

Maybe a MMX/SSE and/or 64-bit version(s) will follow... ;)

 

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By memerim
      #include <GDIPlus.au3> Text2PNG(@ScriptDir & "\x_2.png", 0x7DFFFFFF) ; Transparent text Func Text2PNG($sFile, $iColor) _GDIPlus_Startup() Local $hImage = _GDIPlus_BitmapCreateFromFile ( $sFile ) ;Local $hImage = _GDIPlus_BitmapCreateFromScan0(400, 250) ;$sFile2 = @ScriptDir & "\x_3.png" ;_GDIPlus_ImageSaveToFile($hImage, $sFile2) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $GDIP_TEXTRENDERINGHINT_ANTIALIAS) _GDIPlus_GraphicsClear($hGraphics, $iColor) _GDIPlus_GraphicsDrawString($hGraphics, "Hello", 0, 0, "Arial", 32, 0) _GDIPlus_ImageSaveToFile($hImage, $sFile) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() EndFunc ;==>Text2PNG The image is at 50% transparency, im trying to write the text on it with the same transparency.
      What transparency lvl the text will need to be drawn, to achieve the same transparency as on the image, 50% too? (0x7DFFFFFF)
      But atm it does not draw anything unless i create a new bitmap from scan, whats going on?
       
       
    • By UEZ
      This project has been discontinued!
       
      Here a small tool I wrote to update my Sysinternal tools collection without the need to download always the whole package or visiting the site to check for updates. I know that there are several tools available (also some tools written in AutoIt) but here another one for the collection. It was good exercise for me to code it.
       
       
        
       
       
      Some files from the live web site cannot be downloaded although they are visible!
       
      Here the download link of the source code only: AutoIt Sysinternal Tools Synchronizer v0.99.6 build 2020-09-23 beta.7z  (1557 downloads previously)
      -=> Requires AutoIt version 3.3.13.20 or higher / tested on Win8.1 real machine and some VMs: Win7 / Vista / Win10
       
      Compiled exe only: @MediaFire
       
      Just select the Sysinternal Tools folder or create one and press the synchronize button to download the selected items. Click on AutoIt label (near to left upper corner) to open menu.
       
      Special thanks to LarsJ, Melba23 and mesale0077 for their help. 
       
      I've still some ideas to implement which are more gimmick related, so it is not finished yet...
      If you want to add your language please check out #Region Language. Thanks. 
       
      Please report any bug or if you have any suggestions.
       
      The language of the tool tip from each of the executable in the left list view were automatically created using Google translator and weren't checked for correctness.
       
      Br,
      UEZ
    • By UEZ
      Here another example to mark the desktop to get the marked region for capturing. This example is not perfect and not very fast (room for improvements).
      ;Coded by UEZ build 2020-08-07 beta ;Code cleanup up mLipok ; ;Short instruction: mark area on your desktop and press return key to capture. #include <APISysConstants.au3> #include <Array.au3> ;#include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <ScreenCapture.au3> #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> ; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE ;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAware) Global $__g_hGUI_MarkArea, $__g_hGUI_Bg, $__g_iLabel_TL, $__g_iLabel_TM, $__g_iLabel_TR, $__g_iLabel_LM, $__g_iLabel_RM, $__g_iLabel_BL, $__g_iLabel_BM, _ $__g_iLabel_BR, $__g_iOldCursor, $__g_iW, $__g_iH, $__g_iColor_ResizeDots = 0xFFFFFF, $__g_iBorder = 4, $__g_bSelectionDone = False Global $aRect = _GDIPlus_MarkScreenRegionAnimated() Global $hImage_Capture = _ScreenCapture_Capture(@TempDir & "\Test.png", $aRect[0], $aRect[1], $aRect[0] + $aRect[2] - 1, $aRect[1] + $aRect[3] - 1, False) ShellExecute(@TempDir & "\Test.png") ;_ArrayDisplay($aRect, "Marked area coordinates") Func _GDIPlus_MarkScreenRegionAnimated($bAnim = True) _GDIPlus_Startup() Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hFullScreen) $__g_hGUI_Bg = GUICreate("", $aFullScreen[2], $aFullScreen[3], $aFullScreen[0], $aFullScreen[1], BitOR($WS_CLIPCHILDREN, $WS_POPUP), $WS_EX_TOPMOST) ;to avoid cursor flickering and for proper control read WinSetTrans($__g_hGUI_Bg, "", 0x01) $__g_hGUI_MarkArea = GUICreate("", 1, 1, -1, -1, $bAnim ? $WS_POPUP : BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED), $__g_hGUI_Bg) GUISetBkColor(0xABCDEF, $__g_hGUI_MarkArea) If Not $bAnim Then $__g_iColor_ResizeDots = 0xFF0000 $__g_iLabel_TL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_LM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;left mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_RM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;right mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) GUISetState(@SW_SHOWNA, $__g_hGUI_Bg) GUISetState(@SW_SHOW, $__g_hGUI_MarkArea) $__g_iOldCursor = MouseGetCursor() GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) _WinAPI_SetLayeredWindowAttributes($__g_hGUI_MarkArea, 0xABCDEF, 0xF0) Local $aMPos, $aPrevMPos[2] = [MouseGetPos(0) + 1, MouseGetPos(1) + 1], $iID, $aCI, $iX, $iY, $aOldWinPos, $aOldMPos, $bMoved Local $aGUIStartPos, $iKey_Exit = GUICtrlCreateButton("", $aFullScreen[0] - 10, $aFullScreen[1] - 10, 1, 1), $aAccelKeys[1][2] = [["{ENTER}", $iKey_Exit]] GUISetAccelerators($aAccelKeys, $__g_hGUI_Bg) GUISetAccelerators($aAccelKeys, $__g_hGUI_MarkArea) #forceref $bMoved Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $iKey_Exit If $bAnim Then GUIRegisterMsg($WM_TIMER, "") DllCall("user32.dll", "bool", "KillTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", $iID) GUIRegisterMsg($WM_ERASEBKGND, "") EndIf _GDIPlus_Shutdown() Local $aResult = WinGetPos($__g_hGUI_MarkArea) $aResult[2] = WinGetClientSize($__g_hGUI_MarkArea)[0] $aResult[3] = WinGetClientSize($__g_hGUI_MarkArea)[1] GUIDelete($__g_hGUI_MarkArea) GUIDelete($__g_hGUI_Bg) If Not $__g_bSelectionDone Then $aResult = 0 Return $aResult EndSwitch $aMPos = MouseGetPos() If ($aMPos[0] <> $aPrevMPos[0] Or $aMPos[1] <> $aPrevMPos[1]) And (Not $__g_bSelectionDone) Then WinMove($__g_hGUI_MarkArea, "", $aMPos[0], $aMPos[1]) $aPrevMPos = $aMPos EndIf $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If $aCI[2] And (Not $__g_bSelectionDone) Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $bAnim Then GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") $iID = DllCall("User32.dll", "uint_ptr", "SetTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", 1, "uint", 50, "ptr", 0)[0] EndIf While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) $aMPos = MouseGetPos() $__g_iW = Abs($aMPos[0] - $aGUIStartPos[0]) + 1 $__g_iH = Abs($aMPos[1] - $aGUIStartPos[1]) + 1 If $aMPos[0] < $aGUIStartPos[0] Then $iX = $aMPos[0] Else $iX = $aGUIStartPos[0] EndIf If $aMPos[1] < $aGUIStartPos[1] Then $iY = $aMPos[1] Else $iY = $aGUIStartPos[1] EndIf WinMove($__g_hGUI_MarkArea, "", $iX, $iY, $__g_iW, $__g_iH) UpdateCtrlPos($bAnim) WEnd $__g_bSelectionDone = True GUISetCursor(3, 1, $__g_hGUI_MarkArea) ElseIf $aCI[3] And $__g_bSelectionDone Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If _WinAPI_PtInRectEx(MouseGetPos(0), MouseGetPos(1), $aGUIStartPos[0], $aGUIStartPos[1], $aGUIStartPos[0] + $aGUIStartPos[2], $aGUIStartPos[1] + $aGUIStartPos[3]) Then $aMPos = MouseGetPos() $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) While $aCI[3] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aGUIStartPos[0] - ($aMPos[0] - MouseGetPos(0)), $aGUIStartPos[1] - ($aMPos[1] - MouseGetPos(1)), $__g_iW, $__g_iH) GUISetCursor(0, 1, $__g_hGUI_Bg) GUISetCursor(0, 1, $__g_hGUI_MarkArea) WEnd GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndIf EndIf If $__g_bSelectionDone Then $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If @error Then ContinueLoop Switch $aCI[4] Case $__g_iLabel_TL GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), MouseGetPos(1), $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BR GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TR GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BL GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_LM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_RM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2], $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2], $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case Else GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndSwitch EndIf Until False EndFunc ;==>_GDIPlus_MarkScreenRegionAnimated Func UpdateCtrlPos($bAnim = True) Local Const $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "") $__g_iW = $aGUIStartPos[2] $__g_iH = $aGUIStartPos[3] ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TL, 0, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TM, ($__g_iW - $__g_iBorder) / 2, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_LM, 0, ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_RM, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BL, 0, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BM, ($__g_iW - $__g_iBorder) / 2, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") EndFunc ;==>UpdateCtrlPos Func PlayBorderAnim() Local $aWinPos = WinGetClientSize($__g_hGUI_MarkArea), $iW = $aWinPos[0], $iH = $aWinPos[1] Local Static $fOffset = 0 Local Const $iSize = $__g_iBorder / 2 Local Const $hDC = _WinAPI_GetDC($__g_hGUI_MarkArea) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) Local Const $hPen = _GDIPlus_PenCreate(0xFF0178D7, $iSize), $hPen2 = _GDIPlus_PenCreate(0xFFFFFFFF, $iSize), _ $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000 + $__g_iColor_ResizeDots), $hPen3 = _GDIPlus_PenCreate(0xFF000000) _GDIPlus_PenSetDashStyle($hPen, $GDIP_DASHSTYLEDASHDOT) _GDIPlus_GraphicsClear($hCanvas, 0xFFABCDEF) ;for faster performance direct dll calls DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen2, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipSetPenDashOffset", "handle", $hPen, "float", $fOffset) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) $fOffset += 0.5 _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($__g_hGUI_MarkArea, $hDC) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPen2) _GDIPlus_PenDispose($hPen3) _GDIPlus_BrushDispose($hBrush) EndFunc ;==>PlayBorderAnim Func WM_ERASEBKGND($hWnd, $iMsgm, $wParam, $lParam) ;suppress repainting to avoid flickering but causes some other side effects #forceref $iMsgm, $wParam, $lParam, $hWnd Local Const $hBrush = _WinAPI_CreateSolidBrush(0xEFCDAB) ;BGR format ;~ _WinAPI_RedrawWindow($__g_hGUI_MarkArea, 0, 0, BitOR($RDW_NOERASE, $RDW_NOCHILDREN, $RDW_NOFRAME, $RDW_VALIDATE)) _WinAPI_SetClassLongEx($__g_hGUI_MarkArea, $GCL_HBRBACKGROUND, $hBrush) _WinAPI_DeleteObject($hBrush) Return 0 EndFunc ;==>WM_ERASEBKGND ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode Switch $iMode Case 1 Local $hDC = _WinAPI_GetDC($hGUI) Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0) _WinAPI_ReleaseDC(0, $hDC) Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0) Case 2 ;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle()) Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0) Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0) Case 3 Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0) Local $aResult32 = DllCall("user32.dll", "ptr", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0) Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0) EndSwitch Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext  
      Just press the lmb and move your mouse. When lmb is released you can adjust the size of the window by dragging the white rectangle to any direction. Rmb will move the marked area.
      Press ESC to get the coordinates of the marked region.
      If you have any improvements, please post it here.
       
      Tested on Win10 x64 only.
       
    • By ripdad
      This is a project that I have been working on for several months off and on.
      It's a simple "What You Hear" MP3 @ 320Kbps and WAV audio recorder.
      Features:
      - LoudMax, a Gain Controller and Look-Ahead Limiter
      - Auto Shut-Off after one minute of silence
      - Side-by-Side Simulated LED Meter
      - Running Time Counter
      It started off being a large project, but I eventually stripped it down to its
      bare essentials because I came to realize that it would be very difficult to
      deal with every sound card and every way a PC is set up for audio. It would
      have been a nightmare that I was not willing to go through.
      This project contains the most up-to-date BASS.dll v.2.4.15.0 - December 17, 2019.
      All BASS Dll's are 32bit. Those and the needed UDF's are included in the zip file.
      I will try to explain how it works in the next post.

      Download:
      BASS VST Recorder v1.1.zip
       
    • By Bilgus
      This is an update or derivative work of Beege 's Scrolling Line Graph UDF
      https://www.autoitscript.com/forum/topic/109599-scrolling-line-graph-udf
       
      I noticed a few issues for my use case with the UDF one being that adding a sample required updating the waveform
      High CPU usage went hand in hand with that requirement
      Another issue was just how long updating took to complete
      I've hopefully rectified that with this version
       
      There are a few changes (only 1 line per graph for instance)
      The addition of a function AddSample (uses graphics paths to speed up drawing samples on update) Gridlines are only generated once A sample finished line can be added UpdateGraph allows you to compress the discarded portion of the graph (it looks kinda cool but uses more CPU) Lower Cpu usage Uses real Control Ids - it is a label control underneath so you get click events and can display text when control is disabled Example (Waveform.au3)
       
      Example 2 (peak.au3)
      UDF
      Updated:
      Previous Downloads [38 / 38/ 0]
      SSLG.au3 waveform.au3 Peak.au3
×
×
  • Create New...