Jump to content

Optimization help


Recommended Posts

I have created a code to process a typical bitmap image and create a new bitmap image that is a grayscaled replica of original bitmap.

The code i have works, it just takes an UNGODLY long time to process an image even close to a screenshot (1280x1024)

I'm wondering if anyone here can remove all the redundancies and such, so that maybe my code can process the bitmap faster :D

Code:

#include <Array.au3>

Convert2Greyscale(@DesktopDir&"\test.bmp")


Func Convert2Greyscale($Bmp)
    $File = FileOpen($Bmp, 16)
    $Content= StringTrimLeft(FileRead($File),2)
    FileClose($File)
    $Header = StringLeft($Content, 108)
    $ColorData = StringTrimLeft($Content,108)
    $Pixels = _StringChop($ColorData,6,1)
    _ArrayDelete($Pixels, 0)
    If StringLen($Pixels[Ubound($Pixels)-1])<6 Then 
        Do 
            $Pixels[Ubound($Pixels)-1] &="0"
        Until StringLen($Pixels[Ubound($Pixels)-1])=6
    EndIf
    Dim $NewPixels[UBound($Pixels)],$i=0
    ProgressOn("Processing Image...", "Converting Image to Greyscale...")
    For $x in $Pixels
        $Colors = _StringChop($x, 2)
        For $a = 1 to 3
        Switch $a
            Case 1
                $Colors[$a] = Hex(Dec($Colors[$a])*.11,2);b
            Case 2
                $Colors[$a] = Hex(Dec($Colors[$a])*.59,2);g
            Case 3
                $Colors[$a] = Hex(Dec($Colors[$a])*.3,2);r
        EndSwitch
        Next
        $Gray = Int($Colors[1]+$Colors[2]+$Colors[2])
        $NewPixels[$i] = Hex($gray,2) &  Hex($gray,2) &  Hex($gray,2)
        $i+=1
        ProgressSet($i/UBound($Pixels)*100, Round($i/UBound($Pixels),2)*100&"%"&"   -   "&$i&"/"&UBound($Pixels))
    Next
    ProgressOff()
    Dim $Data=""
    For $b = 0 to UBound($NewPixels)-1
        $Data&=$NewPixels[$b]
    Next
$NewFile= FileOpen(@DesktopDir&"\GREY.bmp",18)
FileWrite($NewFile,"0x"&$Header&$Data)
FileClose($NewFile)
EndFunc

Func _StringChop($string, $size,$show=0)
$count = Ceiling(StringLen($string)/$size)
Dim $array[$count+1], $start = 1
If $Show then ProgressOn("Gathering Resources...", "Gathering Image Resources....")
For $i = 1 To $count
    If $Show then ProgressSet($i/$Count*100, Round($i/$Count,2)*100&"%"&"   -   "&$i&"/"&$Count)
    $array[$i] = StringMid($string, $start, $size)
    $start += $size
Next
If $Show then ProgressOff()
$array[0] = $count
Return $array
EndFunc
Edited by Paulie
Link to comment
Share on other sites

Well, I thought it worked, because it appeared successful on very small test images, however,

I have attached the results of my 4.5 HOUR test run of the script, and i must say the results are less than satisfactory... :\

any idea why this happened?

Link to comment
Share on other sites

Much faster _StringChop is

$array = StringRegExp($ColorData, ".{6}|.{1,6}", 3)

So using that, and with other redundant operations removed (and some bug fixed), hex string/array version could be like

Func Convert2Greyscale_Meh($Bmp)
    Local $File, $Content, $Header, $ColorData, $Pixels, $i=0, $x, $Data="", $Colors, $Grey, $NewFile
    
    $File = FileOpen($Bmp, 16)
    $Content = FileRead($File)
    FileClose($File)
    $Header = BinaryMid($Content, 1, 54)
    $ColorData = Hex(BinaryMid($Content, 55))

    $Pixels = StringRegExp($ColorData, ".{6}|.{1,6}", 3)
    If StringLen($Pixels[Ubound($Pixels)-1])<6 Then
        Do 
            $Pixels[Ubound($Pixels)-1] &="0"
        Until StringLen($Pixels[Ubound($Pixels)-1])=6
    EndIf

    ProgressOn("Processing Image...", "Converting Image to Greyscale...")
    For $x in $Pixels
        $Colors = StringRegExp($x, ".{2}", 3)
        $Grey = Int(Dec($Colors[0])*0.11+Dec($Colors[1])*0.59+Dec($Colors[2])*0.3)
        $Data &= Hex($Grey,2) &  Hex($Grey,2) &  Hex($Grey,2)
        $i+=1
;don't stress the progressbar so much
        If Not Mod($i,UBound($Pixels)/100) Then ProgressSet($i/UBound($Pixels)*100, Round($i/UBound($Pixels),2)*100&"%"&"   -   "&$i&"/"&UBound($Pixels))
    Next
    ProgressOff()

    $NewFile= FileOpen(@DesktopDir&"\GREY.bmp",18)
    FileWrite($NewFile,$Header&$Data)
    FileClose($NewFile)
EndFunc

DllStruct... approach would be faster

Func Convert2Greyscale_StillTooSlow($Bmp)
    Local $File, $Content, $Header, $ColorData, $tData, $i=1, $ByteCount, $Grey, $NewFile
    
    $File = FileOpen($Bmp, 16)
    $Content= FileRead($File)
    FileClose($File)
    $Header = BinaryMid($Content, 1, 54)
    $ColorData = BinaryMid($Content, 55)

    ProgressOn("Processing Image...", "Converting Image to Greyscale...")
    $ByteCount = BinaryLen($ColorData)
    $tData = DllStructCreate("ubyte[" & $ByteCount & "]")
    DllStructSetData($tData, 1, $ColorData)
    While $i < $ByteCount
        $Grey = Int((DllStructGetData($tData, 1, $i)*0.11)+(DllStructGetData($tData, 1, $i+1)*0.59)+(DllStructGetData($tData, 1, $i+2)*0.3))
        DllStructSetData($tData, 1, $Grey, $i)
        DllStructSetData($tData, 1, $Grey, $i+1)
        DllStructSetData($tData, 1, $Grey, $i+2)
        If Not Mod($i-1,$ByteCount/100) Then ProgressSet($i/$ByteCount*100, Round($i/$ByteCount,2)*100&"%"&"   -   "&Int($i/3)&"/"&$ByteCount/3)
        $i += 3
    WEnd
    ProgressOff()

    $ColorData = DllStructGetData($tData, 1)
    $NewFile= FileOpen(@DesktopDir&"\GREY.bmp",18)
    FileWrite($NewFile,$Header&$ColorData)
    FileClose($NewFile) 

EndFunc

but still not nearly fast enough for any practical use on decent size images.

So if you want performance, use some compiled code... Such as:

- It's possible using GDI+, but probably not possible with current GDIPlus.au3 without some additional wrappers (GdipSetImageAttributesColorMatrix & stuff, which would take time to figure out how to implement these with AutoIt's Dll... mechanism).

- ImageMagick COM object

- I think prospeed has greyscale function, and if you're short of time, that's probably your best bet.

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

Well, what you have done is certainly ages faster than mine :D Thanks big time!

I was wondering, does windows have some "API" or "DLL" or whatever that does this really fast?

Because from what I understand, Windows fades to grey when you open the hibernate/shutdown/logoff menu by taking a screenshot and fading it to grey.

All i could find in looking for how windows does it is this:

http://www.codeproject.com/KB/dotnet/DimmerForm.aspx

Edited by Paulie
Link to comment
Share on other sites

Well, what you have done is certainly ages faster than mine :D Thanks big time!

I was wondering, does windows have some "API" or "DLL" or whatever that does this really fast?

Because from what I understand, Windows fades to grey when you open the hibernate/shutdown/logoff menu by taking a screenshot and fading it to grey.

All i could find in looking for how windows does it is this:

http://www.codeproject.com/KB/dotnet/DimmerForm.aspx

If that is what you want to do, then you could just create a gui with it's background color set to black, then use WinSetTrans on your gui(in a loop) to 'fade' the windows behind it..

Link to comment
Share on other sites

If that is what you want to do, then you could just create a gui with it's background color set to black, then use WinSetTrans on your gui(in a loop) to 'fade' the windows behind it..

Tried that, it just made my monitor look darker :D

#Include <GuiConstants.au3>

$Gui =GUICreate("Fade", 2*@DesktopWidth+100, 2*@DesktopHeight+100, 0,0, $WS_POPUP,$WS_EX_TOOLWINDOW)
GUISetBkColor(0x000000)
WinSetTrans($GUI,"", 10)
GUISetState(@SW_SHOW)
For $i = 10 to 180
    WinSetTrans($GUI,"", $i)
Next
Link to comment
Share on other sites

Doing greyscale the GDI+ way:

#Include <GDIPlus.au3>

_GDIPlus_Startup()

$hImage1 = _GDIPlus_ImageLoadFromFile("test.jpg")
$hImage2 = _GDIPlus_ImageGreyscale($hImage1)
_GDIPlus_ImageSaveToFile($hImage2, "test_grey.png")

_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)

_GDIPlus_ShutDown()
Exit

;; _GDIPlus_ImageGreyscale()
;;      Creates a greyscale copy of Image object and returns its handle. To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose()
Func _GDIPlus_ImageGreyscale(Const ByRef $hImage)
    Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap
;;create color matrix data
    $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]")
    ;greyscale values:
    $x = DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _
        DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _
        DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _
        DllStructSetData($tColorMatrix, 4, 1.0, 4) * _
        DllStructSetData($tColorMatrix, 5, 1.0, 5)
;;create an image attributes object and update its color matrix
    $hImgAttrib = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, DllStructGetPtr($tColorMatrix))
;;copy image
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)
;;draw original into copy with attributes
    _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, 0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib)
;;clean up
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphics2)
    _GDIPlus_ImageAttributesDispose($hImgAttrib)

    Return $hBitmap
EndFunc

;;;;; other GDIPlus wrappers ;;;;;

#cs
_GDIPlus_ImageAttributesSetColorMatrix()
    Sets ColorMatrix of ImageAttributes object
    Parameters:
        $hImgAttrib = ImageAttributes object
        $iColorAdjustType = can be:
            ColorAdjustTypeDefault                =  0
            ColorAdjustTypeBitmap                 =  1
            ColorAdjustTypeBrush                  =  2
            ColorAdjustTypePen                    =  3
            ColorAdjustTypeText                   =  4
            ColorAdjustTypeCount                  =  5
            ColorAdjustTypeAny (Reserved)         =  6
        $pColorMatrix = pointer to ColorMatrix structure
        $pGrayMatrix = pointer to GreyMatrix structure
        $iColorMatrixFlags = can be:
            ColorMatrixFlagsDefault               =  0
            ColorMatrixFlagsSkipGrays             =  1
            ColorMatrixFlagsAltGray               =  2
    Return value: True/False
#ce
Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, $pColorMatrix = 0, $pGrayMatrix = 0, $iColorMatrixFlags = 0)
    Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr",$hImgAttrib, "int",$iColorAdjustType, _
                                            "int",$fEnable, "ptr",$pColorMatrix, "ptr",$pGrayMatrix, "int",$iColorMatrixFlags)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

;;Creates ImageAttributes object
Func _GDIPlus_ImageAttributesCreate()
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0)
    Return SetError($aResult[0], 0, $aResult[1])
EndFunc

;;Deletes ImageAttributes object
Func _GDIPlus_ImageAttributesDispose($hImgAttrib)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

;; _GDIPlus_GraphicsDrawImageRectRectEx()
;; Same as _GDIPlus_GraphicsDrawImageRectRect(), but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object)
Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _
            $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", $iSrcWidth, "int", _
            $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

;;=============================

"be smart, drink your wine"

Link to comment
Share on other sites

And Siao's function makes the fade to Grey a breeze!! :D

Very nice!!

#Include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <GuiConstants.au3>
HotKeySet("{ESC}","Quit")
func Quit()
    Exit
EndFunc
$Path = @TempDir&"\ImgTemp.jpg"
$Path2 =  @TempDir&"\ImgTemp_Grey.jpg"
$Bitmap= _ScreenCapture_Capture("", 0,0,-1,-1,False)
_ScreenCapture_SaveImage($Path, $Bitmap)
_WinAPI_DeleteObject($Bitmap)
_GDIPlus_Startup()
$hImage1 = _GDIPlus_ImageLoadFromFile($Path)
$hImage2 = _GDIPlus_ImageGreyscale($hImage1)
_GDIPlus_ImageSaveToFile($hImage2, $Path2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
_GDIPlus_ShutDown()
$Gui = GUICreate("Fade", @DesktopWidth, @DesktopHeight, 0,0,$WS_POPUP, BitOR($WS_EX_TOPMOST,$WS_EX_TOOLWINDOW))
GUICtrlCreatePic($Path2,0,0,@DesktopWidth,@DesktopHeight)
WinSetTrans($GUI,"", 0)
GUISetState()
For $i = 1 to 255
WinSetTrans($GUI,"", $i)
Next
While 1
    sleep(100)
WEnd


;; _GDIPlus_ImageGreyscale()
;;    Creates a greyscale copy of Image object and returns its handle. To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose()
Func _GDIPlus_ImageGreyscale(Const ByRef $hImage)
    Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap
;;create color matrix data
    $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]")
    ;greyscale values:
    $x= DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _
        DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _
        DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _
        DllStructSetData($tColorMatrix, 4, 1.0, 4) * _
        DllStructSetData($tColorMatrix, 5, 1.0, 5)
;;create an image attributes object and update its color matrix
    $hImgAttrib = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, DllStructGetPtr($tColorMatrix))
;;copy image
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)
;;draw original into copy with attributes
    _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, 0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib)
;;clean up
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphics2)
    _GDIPlus_ImageAttributesDispose($hImgAttrib)

    Return $hBitmap
EndFunc

Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, $pColorMatrix = 0, $pGrayMatrix = 0, $iColorMatrixFlags = 0)
    Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr",$hImgAttrib, "int",$iColorAdjustType, _
                                            "int",$fEnable, "ptr",$pColorMatrix, "ptr",$pGrayMatrix, "int",$iColorMatrixFlags)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

;;Creates ImageAttributes object
Func _GDIPlus_ImageAttributesCreate()
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0)
    Return SetError($aResult[0], 0, $aResult[1])
EndFunc

;;Deletes ImageAttributes object
Func _GDIPlus_ImageAttributesDispose($hImgAttrib)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

;; _GDIPlus_GraphicsDrawImageRectRectEx()
;; Same as _GDIPlus_GraphicsDrawImageRectRect(), but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object)
Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _
            $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", $iSrcWidth, "int", _
            $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc
Edited by Paulie
Link to comment
Share on other sites

Note that you can use _GDIPlus_BitmapCreateFromHBITMAP() to create a GDI+ bitmap object from memory bitmap returned by _ScreenCapture_Capture(), and pass it to _GDIPlus_ImageGreyscale, to avoid writing/reading a temp file (_ScreenCapture_SaveImage/_GDIPlus_ImageLoadFromFile).

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

I have created a UDF demonstrating my best efforts at simulating XP's fade to grey, Unfortunately, i had to write a temp script so i could have it fade while the message box was still open. i dunno how useful it will be to anyone, but I know i will be using it :D

HotKeySet("{ESC}","Quit")
$Answer = GreyScaleMsgbox(4,"Test", "Do you want something important to happen?")

Func GreyScaleMsgbox($Flag, $Title, $Text, $Timeout=0,$Step=5)
    $Indicator = Random(1000000,9999999,1)  
    $String = " #NoTrayicon"&@CRLF
    $String &=' #Include <GDIPlus.au3>'&@CRLF
    $String &=' #Include <ScreenCapture.au3>'&@CRLF
    $String &=' #Include <GuiConstants.au3>'&@CRLF
    $String &=' _GDIPlus_Startup()'&@CRLF
    $String &='     $Path =  @TempDir&"\ImgTemp_Grey.jpg"'&@CRLF
    $String &='     $hBitmap= _ScreenCapture_Capture("", 0,0,@DesktopWidth,-1,False)'&@CRLF
    $String &='     $Bitmap= _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)'&@CRLF
    $String &='     $hImage= _GDIPlus_ImageGreyscale($Bitmap)'&@CRLF
    $String &='     _GDIPlus_ImageSaveToFile($hImage, $Path)'&@CRLF
    $String &='     _GDIPlus_ImageDispose($hImage)'&@CRLF
    $String &='     _WinAPI_DeleteObject($Bitmap)'&@CRLF
    $String &=' _GDIPlus_ShutDown()'&@CRLF
    $String &=' $GUI = GUICreate(String("'&$Indicator&'"), @DesktopWidth, @DesktopHeight, 0,0,$WS_POPUP, BitOR($WS_EX_TOPMOST,$WS_EX_TOOLWINDOW))'&@CRLF
    $String &='     $Pic=GUICtrlCreatePic($Path,0,0,@DesktopWidth,@DesktopHeight)'&@CRLF
    $String &=' GUISetState(@SW_DISABLE)'&@CRLF
    $String &=' WinSetTrans($GUI,"", 0)'&@CRLF
    $String &=' GUISetState(@SW_SHOW)'&@CRLF
    $String &=' Do'&@CRLF
    $String &='     Sleep(100)'&@CRLF
    $String &=' Until WinExists("'&$Title&'","'&$Text&'")'&@CRLF
    $String &=' WinSetOnTop("'&$Title&'","'&$Text&'",1)'&@CRLF
    $String &=' For $i = 0 to 255 step '&$Step&@CRLF
    $String &='     WinSetTrans($GUI,"", $i)'&@CRLF
    $String &='     If Not WinExists("'&$Title&'","'&$Text&'") Then Exit'&@CRLF
    $String &=' Next'&@CRLF
    $String &=' Opt("WinTitleMatchMode",4)'&@CRLF
    $String &=' WinSetState("Classname=Shell_TrayWnd", "", @SW_HIDE)'&@CRLF
    $String &=' WinSetState("Program Manager", "", @SW_HIDE)'&@CRLF
    $String &=' Opt("WinTitleMatchMode",1)'&@CRLF
    $String &=' While 1'&@CRLF
    $String &='     WinSetOnTop("'&$Title&'","'&$Text&'",1)'&@CRLF
    $String &='     If Not WinActive("'&$Title&'","'&$Text&'") Then WinActivate("'&$Title&'","'&$Text&'")'&@CRLF
    $String &='     If Not WinExists("'&$Title&'","'&$Text&'") Then'&@CRLF
    $String &='         Opt("WinTitleMatchMode",4)'&@CRLF
    $String &='         WinSetState("Classname=Shell_TrayWnd", "", @SW_SHOW)'&@CRLF
    $String &='         WinSetState("Program Manager", "", @SW_SHOW)'&@CRLF
    $String &='         Opt("WinTitleMatchMode",1)'&@CRLF
    $String &='         Exit'&@CRLF
    $String &='     EndIf'&@CRLF
    $String &=' WEnd'&@CRLF
    $String &=' Func _GDIPlus_ImageGreyscale(Const ByRef $hImage)'&@CRLF
    $String &='   Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage),$iH=_GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap'&@CRLF
    $String &='   $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]")'&@CRLF
    $String &='   $x= DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _'&@CRLF
    $String &='       DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _'&@CRLF
    $String &='       DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _'&@CRLF
    $String &='       DllStructSetData($tColorMatrix, 4, 1.0, 4) * _'&@CRLF
    $String &='       DllStructSetData($tColorMatrix, 5, 1.0, 5)'&@CRLF
    $String &='   $hImgAttrib = _GDIPlus_ImageAttributesCreate()'&@CRLF
    $String &='   _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, DllStructGetPtr($tColorMatrix))'&@CRLF
    $String &='   $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)'&@CRLF
    $String &='   $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)'&@CRLF
    $String &='   $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)'&@CRLF
    $String &='   _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, 0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib)'&@CRLF
    $String &='   _GDIPlus_GraphicsDispose($hGraphics)'&@CRLF
    $String &='   _GDIPlus_GraphicsDispose($hGraphics2)'&@CRLF
    $String &='   _GDIPlus_ImageAttributesDispose($hImgAttrib)'&@CRLF
    $String &='   Return $hBitmap'&@CRLF
    $String &=' EndFunc'&@CRLF
    $String &=' Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, $pColorMatrix = 0, $pGrayMatrix = 0, $iColorMatrixFlags = 0)'&@CRLF
    $String &='   Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr",$hImgAttrib, "int",$iColorAdjustType, _'&@CRLF
    $String &='                                           "int",$fEnable, "ptr",$pColorMatrix, "ptr",$pGrayMatrix, "int",$iColorMatrixFlags)'&@CRLF
    $String &='   Return SetError($aResult[0], 0, $aResult[0] = 0)'&@CRLF
    $String &=' EndFunc'&@CRLF
    $String &=' Func _GDIPlus_ImageAttributesCreate()'&@CRLF
    $String &='    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0)'&@CRLF
    $String &='    Return SetError($aResult[0], 0, $aResult[1])'&@CRLF
    $String &=' EndFunc'&@CRLF
    $String &=' Func _GDIPlus_ImageAttributesDispose($hImgAttrib)'&@CRLF
    $String &='    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib)'&@CRLF
    $String &='    Return SetError($aResult[0], 0, $aResult[0] = 0)'&@CRLF
    $String &=' EndFunc'&@CRLF
    $String &=' Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0)'&@CRLF
    $String &='    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _'&@CRLF
    $String &='            $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", $iSrcWidth, "int", _'&@CRLF
    $String &='            $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0)'&@CRLF
    $String &='    Return SetError($aResult[0], 0, $aResult[0] = 0)'&@CRLF
    $String &=' EndFunc'
    $TempPath=@TempDir&"\FadeBoxTemp.au3"
    $File = FileOpen($TempPath,2)
    FileWrite($File, $String)
    FileClose($File)
    Run('AutoIt3.exe '&$TempPath)
    Do 
        Sleep(100)
    Until WinExists($Indicator)
    $Output = MsgBox($Flag, $Title,$Text, $Timeout)
    Return $Output
EndFunc
Func Quit()
    Exit
EndFunc
Link to comment
Share on other sites

@Paulie

You can eliminate that second temp file.

#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)
HotKeySet("{ESC}", "Quit")

Func Quit()
    Exit
EndFunc   ;==>Quit

Global Const $STM_SETIMAGE = 0x0172
Global Const $IMAGE_BITMAP = 0
Global $hBitmap, $hImage1, $hImage2, $oldBitmap
Global $hGui, $hPic

_GDIPlus_Startup()
$hBitmap = _ScreenCapture_Capture("", 0, 0, -1, -1, False)
$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hImage2 = _GDIPlus_ImageGreyscale($hImage1)
_GDIPlus_ImageDispose($hImage1)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage2, 0x00000000)
$hGui = GUICreate("Fade", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, _
        BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
$hPic = GUICtrlCreatePic("", 0, 0, @DesktopWidth, @DesktopHeight)
$hPic = GUICtrlGetHandle($hPic)

If IsHWnd($hPic) Then
    $oldBitmap = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", _
            $hPic, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
    If $oldBitmap[0] Then
        _WinAPI_DeleteObject($oldBitmap[0]) ; not needed in this usage,
        ; but necessary to prevent resource leaks when SendMessage used to
        ; replace existing image.
    EndIf
EndIf
_GDIPlus_ImageDispose($hImage2)
_GDIPlus_Shutdown()

WinSetTrans($hGui, "", 0)
GUISetState()

For $i = 1 To 255 Step 5
    WinSetTrans($hGui, "", $i)
Next

While 1
    Sleep(100)
WEnd


;; _GDIPlus_ImageGreyscale()
;;    Creates a greyscale copy of Image object and returns its handle.
;;    To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose()
Func _GDIPlus_ImageGreyscale(Const ByRef $hImage)
    Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), _
            $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap
    ;;create color matrix data
    $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]")
    ;greyscale values:
    $x = DllStructSetData($tColorMatrix, 1, 0.3, 1) _
             * DllStructSetData($tColorMatrix, 1, 0.3, 2) _
             * DllStructSetData($tColorMatrix, 1, 0.3, 3) _
             * DllStructSetData($tColorMatrix, 2, 0.59, 1) _
             * DllStructSetData($tColorMatrix, 2, 0.59, 2) _
             * DllStructSetData($tColorMatrix, 2, 0.59, 3) _
             * DllStructSetData($tColorMatrix, 3, 0.11, 1) _
             * DllStructSetData($tColorMatrix, 3, 0.11, 2) _
             * DllStructSetData($tColorMatrix, 3, 0.11, 3) _
             * DllStructSetData($tColorMatrix, 4, 1.0, 4) _
             * DllStructSetData($tColorMatrix, 5, 1.0, 5)
    ;;create an image attributes object and update its color matrix
    $hImgAttrib = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, _
            DllStructGetPtr($tColorMatrix))
    ;;copy image
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    ;;draw original into copy with attributes
    _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, _
            0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib)
    ;;clean up
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphics2)
    _GDIPlus_ImageAttributesDispose($hImgAttrib)

    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageGreyscale

Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, _
        $pColorMatrix = 0, $pGreyMatrix = 0, $iColorMatrixFlags = 0)
    Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", _
            "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", $iColorAdjustType, _
            "int", $fEnable, "ptr", $pColorMatrix, "ptr", $pGreyMatrix, "int", $iColorMatrixFlags)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_ImageAttributesSetColorMatrix

;;Creates ImageAttributes object
Func _GDIPlus_ImageAttributesCreate()
    Local $aResult = DllCall($ghGDIPDll, "int", _
            "GdipCreateImageAttributes", "ptr*", 0)
    Return SetError($aResult[0], 0, $aResult[1])
EndFunc   ;==>_GDIPlus_ImageAttributesCreate

;;Deletes ImageAttributes object
Func _GDIPlus_ImageAttributesDispose($hImgAttrib)
    Local $aResult = DllCall($ghGDIPDll, "int", _
            "GdipDisposeImageAttributes", "ptr", $hImgAttrib)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_ImageAttributesDispose

;; _GDIPlus_GraphicsDrawImageRectRectEx()
;; Same as _GDIPlus_GraphicsDrawImageRectRect(),
;; but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object)
Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, _
        $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", _
            $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _
            $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", _
            $iSrcWidth, "int", $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_GraphicsDrawImageRectRectEx

I see fascists...

Link to comment
Share on other sites

Playing with the parameters of the $tColorMatrix structure in Rover's example, I found colour shading is possible, not just gray.

Gray (Original)

$x= DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.4, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _

DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.7, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _

DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.2, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _

DllStructSetData($tColorMatrix, 4, 1.0, 4) * _

DllStructSetData($tColorMatrix, 5, 1.0, 5)

Pink

$x= DllStructSetData($tColorMatrix, 1, 0.4, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _

DllStructSetData($tColorMatrix, 2, 0.7, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _

DllStructSetData($tColorMatrix, 3, 0.2, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _

DllStructSetData($tColorMatrix, 4, 1.0, 4) * _

DllStructSetData($tColorMatrix, 5, 1.0, 5)

Yellow

$x= DllStructSetData($tColorMatrix, 1, 0.4, 1) * DllStructSetData($tColorMatrix, 1, 0.4, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _

DllStructSetData($tColorMatrix, 2, 0.7, 1) * DllStructSetData($tColorMatrix, 2, 0.7, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _

DllStructSetData($tColorMatrix, 3, 0.2, 1) * DllStructSetData($tColorMatrix, 3, 0.2, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _

DllStructSetData($tColorMatrix, 4, 1.0, 4) * _

DllStructSetData($tColorMatrix, 5, 1.0, 5)

Green

$x= DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.4, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _

DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.7, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _

DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.2, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _

DllStructSetData($tColorMatrix, 4, 1.0, 4) * _

DllStructSetData($tColorMatrix, 5, 1.0, 5)

Blue

$x= DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.4, 3) * _

DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.7, 3) * _

DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.2, 3) * _

DllStructSetData($tColorMatrix, 4, 1.0, 4) * _

DllStructSetData($tColorMatrix, 5, 1.0, 5)

A formula, ALPHA = 255 - ((RED * 0.299) + (GREEN * 0.587) + (BLUE * 0.114)), helped.

I change the width and height in these line - a personal choice,

$Gui = GUICreate("Fade", @DesktopWidth/2, @DesktopHeight/2, 0,0,$WS_POPUP, BitOR($WS_EX_TOPMOST,$WS_EX_TOOLWINDOW))

GUICtrlCreatePic($Path2,0,0,@DesktopWidth/2,@DesktopHeight/2)

The first run produced instant panic. I thought the screen had frozen to gray. I found the escape button.

Link to comment
Share on other sites

  • 9 months later...

How I can use that formula? Please explain, I need for some my own colors ;p

[quote name='dbzfanatic' post='609696' date='Nov 26 2008, 08:46 AM']This is a help forum not a "write this for me" forum.[/quote](Sorry for bad English) :)

Link to comment
Share on other sites

You guys are so sharp!

This is really cool.

Kudos to Siao, Paulie, Rover and Malkey!

I noticed a pattern in those color tables, and found it doesn't seem necessary to assign a return value to $x from the DllStructSetData statements, and that all the multiplication doesn't seem required either. So, I came up with this replacement for _GDIPlus_ImageGreyscale():

;; _GDIPlus_ImageGreyscale()
;;  Creates a greyscale copy of Image object and returns its handle.
;;  To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose()
Func _GDIPlus_ImageGreyscale(Const ByRef $hImage)
    Local $tColorMatrix, $y, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), _
            $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap
  ;;create color matrix data
    $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]")
  ;greyscale values:
   ;greyscale values:
    local $huetable[7][10] = [[0, .3, .3, .3, .59, .59, .59, .11, .11, .11], _; Grey 
                              [0, .4, .3, .3, .7, .59, .59, .2, .11, .11], _  ; Red
                              [0, .4, .3, .4, .7, .59, .7, .2, .11, .2], _  ; Purple
                              [0, .3, .3, .4, .59, .59, .7, .11, .11, .2], _  ; Blue
                              [0, .4, .4, .3, .7, .7, .59, .2, .2, .11], _  ; Yellow
                              [0, .3, .4, .3, .59, .7, .59, .11, .2, .11], _  ; Green
                              [0, .3, .4, .4, .59, .7, .7, .11, .2, .2]]      ; Aqua
    Local $hue = 2; select the color scheme for the fade
    Local $y = 0
    For $x = 1 to 3
        For $z = 1 to 3
            $y +=1
            DllStructSetData($tColorMatrix, $x, $huetable[$hue][$y], $z)
        Next
    Next
    DllStructSetData($tColorMatrix, 4, 1.0, 4)
    DllStructSetData($tColorMatrix, 5, 1.0, 5)

  ;;create an image attributes object and update its color matrix
    $hImgAttrib = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, _
            DllStructGetPtr($tColorMatrix))
  ;;copy image
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)
  ;;draw original into copy with attributes
    _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, _
            0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib)
  ;;clean up
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphics2)
    _GDIPlus_ImageAttributesDispose($hImgAttrib)

    Return $hBitmap
EndFunc ;==>_GDIPlus_ImageGreyscale

I can't say if this affects the timing of the fade, it does appear to run just as smoothly.

Of course, $hue could be declared somewhere above as Global and set outside the function.

EDIT: Added Purple and Aqua schemes

Edited by Spiff59
Link to comment
Share on other sites

I chopped up the code calling these GDI+ functions to make it easier for me to play with (test).

I've assigned hotkeys 0 through 9 to switch between the colormatrix schemes in the table. I found what MicroSoft considers "sepia" a while ago and added that as the eighth element in the table. The last 2 elements (keys 8 and 9) aren't defined in the table, so there are a couple slots to mess with and come up with more colors? I set the up and down arrow keys to adjust the 'alpha' just to see what that did.

#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)
For $x = 0 to 9
    HotKeySet("{" & $x & "}", "SetHue")
Next
HotKeySet("{UP}", "AlphaUp")
HotKeySet("{DOWN}", "AlphaDown")
HotKeySet("{ESC}", "Quit")

Global Const $STM_SETIMAGE = 0x0172
Global Const $IMAGE_BITMAP = 0
Global $hBitmap, $hImage1, $hImage2, $oldBitmap
Global $hGui, $hPic
;colormatrix values:              RED  GREEN  BLUE   R   G   B   R   G   B
Global $huetable[10][10] = [["Grey",   .299, .299, .299, .587, .587, .587, .114, .114, .114], _ 
                            ["Red" ,   .400, .299, .299, .700, .587, .587, .200, .114, .114], _ 
                            ["Purple", .400, .299, .400, .700, .587, .700, .200, .114, .200], _ 
                            ["Blue",   .299, .299, .400, .587, .587, .700, .114, .114, .200], _ 
                            ["Yellow", .400, .400, .299, .700, .700, .587, .200, .200, .114], _ 
                            ["Green",  .299, .400, .299, .587, .700, .587, .114, .200, .114], _ 
                            ["Aqua",   .299, .400, .400, .587, .700, .700, .114, .200, .200], _ 
                            ["Sepia",  .393, .349, .272, .769, .686, .534, .189, .168, .131], _ 
                            ["???", .000, .000, .000, .000, .000, .000, .000, .000, .000], _ 
                            ["???", .000, .000, .000, .000, .000, .000, .000, .000, .000]]   
Global $hue = 0, $alpha = 1

; Main loop ---------------------------------------------------------------------------------
_GDIPlus_Startup()
$hBitmap = _ScreenCapture_Capture("", 0, 0, -1, -1, False)
$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
Fade()
While 1
    Sleep(100)
WEnd
Exit

;--------------------------------------------------------------------------------------------
Func SetHue()
    GUIDelete($hGui)
    $hue = StringMid(@HotKeyPressed, 2, 1)
    Fade()
Endfunc

Func AlphaUp()
    If $alpha < 1 Then
        $alpha += .1
        GUIDelete($hGui)
        Fade()
    EndIf
Endfunc

Func AlphaDown()
    If $alpha > 0 Then 
        $alpha -= .1
        GUIDelete($hGui)
        Fade()
    EndIf
Endfunc

Func Fade()
    $hImage2 = _GDIPlus_ImageGreyscale($hImage1)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage2, 0x00000000)
    $hGui = GUICreate("Fade", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
    $hPic = GUICtrlCreatePic("", 0, 0, @DesktopWidth, @DesktopHeight)
    $hPic = GUICtrlGetHandle($hPic)

    If IsHWnd($hPic) Then
        $oldBitmap = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", _
           $hPic, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
;       If $oldBitmap[0] Then
;           _WinAPI_DeleteObject($oldBitmap[0]); not needed in this usage,
    ; but necessary to prevent resource leaks when SendMessage used to
    ; replace existing image.
;       EndIf
    EndIf
    _GDIPlus_ImageDispose($hImage2)
    WinSetTrans($hGui, "", 0)
    GUISetState()
    ToolTip("Hue: " & $huetable[$hue][0] & "    Alpha: " & StringFormat("%.1f",$alpha))

    For $i = 1 To 255 Step 1; Step 5 for faster fade
        WinSetTrans($hGui, "", $i)
    Next
Endfunc
    
Func Quit()
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_Shutdown()
    Exit
EndFunc ;==>Quit

;--------------------------------------------------------------------------------------------
;; _GDIPlus_ImageGreyscale()
;;  Creates a greyscale copy of Image object and returns its handle.
;;  To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose()
Func _GDIPlus_ImageGreyscale(Const ByRef $hImage)
    Local $tColorMatrix, $y, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), _
            $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap
;;create color matrix data
    $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]")
    Local $y = 0
    For $x = 1 to 3
        For $z = 1 to 3
            $y +=1
            DllStructSetData($tColorMatrix, $x, $huetable[$hue][$y], $z)
        Next
    Next
    DllStructSetData($tColorMatrix, 4, $alpha, 4); Alpha?
    DllStructSetData($tColorMatrix, 5, 1.0, 5); dummy for internal addition

;;create an image attributes object and update its color matrix
    $hImgAttrib = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, _
            DllStructGetPtr($tColorMatrix))
;;copy image
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)
;;draw original into copy with attributes
    _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, _
            0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib)
;;clean up
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphics2)
    _GDIPlus_ImageAttributesDispose($hImgAttrib)

    Return $hBitmap
EndFunc;==>_GDIPlus_ImageGreyscale

Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, _
        $pColorMatrix = 0, $pGreyMatrix = 0, $iColorMatrixFlags = 0)
    Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", _
            "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", $iColorAdjustType, _
            "int", $fEnable, "ptr", $pColorMatrix, "ptr", $pGreyMatrix, "int", $iColorMatrixFlags)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_GDIPlus_ImageAttributesSetColorMatrix

;;Creates ImageAttributes object
Func _GDIPlus_ImageAttributesCreate()
    Local $aResult = DllCall($ghGDIPDll, "int", _
            "GdipCreateImageAttributes", "ptr*", 0)
    Return SetError($aResult[0], 0, $aResult[1])
EndFunc ;==>_GDIPlus_ImageAttributesCreate

;;Deletes ImageAttributes object
Func _GDIPlus_ImageAttributesDispose($hImgAttrib)
    Local $aResult = DllCall($ghGDIPDll, "int", _
            "GdipDisposeImageAttributes", "ptr", $hImgAttrib)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_GDIPlus_ImageAttributesDispose

;; _GDIPlus_GraphicsDrawImageRectRectEx()
;; Same as _GDIPlus_GraphicsDrawImageRectRect(),
;; but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object)
Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, _
        $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", _
            $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _
            $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", _
            $iSrcWidth, "int", $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_GDIPlus_GraphicsDrawImageRectRectEx

Run it and bang on some numeric keys...

Edited by Spiff59
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...