Sign in to follow this  
Followers 0
spudw2k

Plasma_kIt

7 posts in this topic

#1 ·  Posted (edited)

Here's a fun tool I put together.  It's a Plasma sandbox.  More features to come.

This page was a useful resource for learning about this kind of Plasma implementation.

Warning! Not Epileptic Friendly (probably)! Use at own Risk!
I tried to curve the "default/initial" Plasma patterns so they aren't too erratic.  That doesn't mean you can't alter the Plasmas to be more erratic.  If you are sensitive to flashing colors and lights, use due caution.  

#Region - Includes and Globals
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
#include <GuiComboBox.au3>
#include <SliderConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <Misc.au3>

;#include <Array.au3>

Opt("GUIOnEventMode", 1)
Local $hDLL = DllOpen("user32.dll")

Global Const $iWinMinWidth = @DesktopWidth * .25
Global Const $iWinMinHeight = @DesktopHeight * .25
Global $bIsPlaying = True, $bIsDrawing = False
Global $hTimerFPS
Global $iRows = 16, $iCols = 16
Global $iDisplayPlasma = 0, $iSelectPlasma = 0

Global $aPlasmaShapes[4] = ["($iX)", "($iY)", "($iX + $iY)", "Sqrt(($iX * $iX) + ($iY * $iY))"]
;~ Global $aPlasmas[4][7] = [[0, Random(6, 14, 1), 0, 0, 1, 0, 0], [1, Random(6, 14, 1), 0, 0, 0, 0, 0], [2, Random(8, 16,1 ), 0, 0, 1, 0, 0], [3, Random(8, 16, 1), 0, 0, Random(0,1,1), 0, 0]] ;Sine Wave | Spread | Position | Rotation | Spread Motion | Position Motion | Rotation Motion
Global $aPlasmas[4][7] = [[0, Random(6, 14, 1), 0, 0, 0, 0, 0], [1, Random(6, 14, 1), 0, 0, 0, 0, 0], [2, Random(8, 16,1 ), 0, 0, 0, 0, 0], [3, Random(8, 16, 1), 0, 0, 0, 0, 0]] ;Sine Wave | Spread | Position | Rotation | Spread Motion | Position Motion | Rotation Motion

Global $aPallete[256]
Global $aPalleteSettings[3][3] = [[0, 128, 128], [-1.75, 128, 128], [1.75, 128, 128]] ;Position | Spread | Value
Global $aPalleteDefaults = $aPalleteSettings
Global $iPalleteShift = 0, $bPalleteShift = True, $iPalletShiftDirection = -5
#EndRegion - Includes and Globals
#Region - Main GUI
Global $aGUI[1] = ["id|hWnd"]
Global Enum $hGUI = 1, $idMnuFile, $idMnuFileExit, $idMnuFilePlay, $idMnuOptions, $idMnuOptionsPallete, $idMnuOptionsPalleteShift, $idMnuOptionsEditor, $idMnuOptionsZoom, $idMnuOptionsZoomIn, $idMnuOptionsZoomOut, $iGUILast
ReDim $aGUI[$iGUILast]
Global Const $sVersion = "0.1"
Global Const $sTitle = "Plasma_kIt - Version " & $sVersion

$aGUI[$hGUI] = GUICreate($sTitle, $iWinMinWidth, $iWinMinHeight, -1, -1, BitOR($WS_SIZEBOX, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX))
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
$aGUI[$idMnuFile] = GUICtrlCreateMenu("&File")
$aGUI[$idMnuFilePlay] = GUICtrlCreateMenuItem("&Pause", $aGUI[$idMnuFile])
GUICtrlSetOnEvent(-1, "_PlayToggle")
$aGUI[$idMnuFileExit] = GUICtrlCreateMenuItem("E&xit", $aGUI[$idMnuFile])
GUICtrlSetOnEvent(-1, "_Exit")
$aGUI[$idMnuOptions] = GUICtrlCreateMenu("&Options")
$aGUI[$idMnuOptionsPallete] = GUICtrlCreateMenuItem("Pallete Mixer", $aGUI[$idMnuOptions])
GUICtrlSetOnEvent(-1, "_GUIPallete_Show")
$aGUI[$idMnuOptionsPalleteShift] = GUICtrlCreateMenuItem("Pallete Shift", $aGUI[$idMnuOptions])
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlSetOnEvent(-1, "_GUIPallete_ShiftToggle")
$aGUI[$idMnuOptionsEditor] = GUICtrlCreateMenuItem("Plasma Editor", $aGUI[$idMnuOptions])
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_Show")
$aGUI[$idMnuOptionsZoom] = GUICtrlCreateMenu("Zoom", $aGUI[$idMnuOptions])
$aGUI[$idMnuOptionsZoomIn] = GUICtrlCreateMenuItem("Zoom In" & @TAB & "+", $aGUI[$idMnuOptionsZoom])
GUICtrlSetOnEvent(-1, "_Zoom")
$aGUI[$idMnuOptionsZoomOut] = GUICtrlCreateMenuItem("Zoom Out" & @TAB & "-", $aGUI[$idMnuOptionsZoom])
GUICtrlSetOnEvent(-1, "_Zoom")
_GDIPlus_Startup() ;Start GDI+ UDF
Global Const $hDC = _WinAPI_GetDC($aGUI[$hGUI])
Global Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, @DesktopWidth, @DesktopHeight)
Global Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
$hBackbuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
;_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing)
$hBrush = _GDIPlus_BrushCreateSolid(0x00000000) ;Brush for Coloring/Painting LED Pixels

Local $aAccelKeys[5][2] = [["{+}", $aGUI[$idMnuOptionsZoomIn]], ["{NUMPADADD}", $aGUI[$idMnuOptionsZoomIn]], ["{-}", $aGUI[$idMnuOptionsZoomOut]], ["{NUMPADSUB}", $aGUI[$idMnuOptionsZoomOut]], ["{pause}", $aGUI[$idMnuFilePlay]]]
GUISetAccelerators($aAccelKeys)
#EndRegion - Main GUI
#Region - Pallete Mixer GUI
Global $aGUIPallete[1] = ["id|hWnd"]
Global Enum $hGUIPallete = 1, $idSliderRPosition, $idSliderRValue, $idSliderRSpread, $idSliderGPosition, $idSliderGValue, _
        $idSliderGSpread, $idSliderBPosition, $idSliderBValue, $idSliderBSpread, $idBtnResetPallete, $iGUIPalleteLast
ReDim $aGUIPallete[$iGUIPalleteLast]
$aGUIPallete[$hGUIPallete] = GUICreate("Pallete Mixer", 338, 260, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIPallete_Hide")
$aGUIPallete[$idSliderRPosition] = GUICtrlCreateSlider(8, 132, 97, 33, $TBS_ENABLESELRANGE)
GUICtrlSetLimit(-1, 20, -20)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")
$aGUIPallete[$idSliderRValue] = GUICtrlCreateSlider(48, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE))
GUICtrlSetLimit(-1, 128, 0)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")
$aGUIPallete[$idSliderRSpread] = GUICtrlCreateSlider(8, 168, 97, 33, $TBS_ENABLESELRANGE)
GUICtrlSetLimit(-1, 24, 2)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")

$aGUIPallete[$idSliderGPosition] = GUICtrlCreateSlider(120, 132, 97, 33, $TBS_ENABLESELRANGE)
GUICtrlSetLimit(-1, 20, -20)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")
$aGUIPallete[$idSliderGValue] = GUICtrlCreateSlider(160, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE))
GUICtrlSetLimit(-1, 128, 0)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")
$aGUIPallete[$idSliderGSpread] = GUICtrlCreateSlider(120, 168, 97, 33, $TBS_ENABLESELRANGE)
GUICtrlSetLimit(-1, 24, 2)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")

$aGUIPallete[$idSliderBPosition] = GUICtrlCreateSlider(232, 132, 97, 33, $TBS_ENABLESELRANGE)
GUICtrlSetLimit(-1, 20, -20)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")
GUICtrlSetData(-1, 9)
$aGUIPallete[$idSliderBValue] = GUICtrlCreateSlider(272, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE))
GUICtrlSetLimit(-1, 128, 0)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")
$aGUIPallete[$idSliderBSpread] = GUICtrlCreateSlider(232, 168, 97, 33, $TBS_ENABLESELRANGE)
GUICtrlSetLimit(-1, 24, 2)
GUICtrlSetData(-1, 11)
;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange")

GUICtrlCreateLabel("RED", 46, 200, 30, 20)
GUICtrlCreateLabel("GREEN", 150, 200, 38, 20)
GUICtrlCreateLabel("BLUE", 268, 200, 30, 20)
$aGUIPallete[$idBtnResetPallete] = GUICtrlCreateButton("Reset", 136, 236, 67, 17)
GUICtrlSetOnEvent(-1, "_GUIPallete_Reset")

GUISetAccelerators($aAccelKeys)

Global Const $hDCPallete = _WinAPI_GetDC($aGUIPallete[$hGUIPallete])
Global Const $hHBitmapPallete = _WinAPI_CreateCompatibleBitmap($hDCPallete, 320, 40)
Global Const $hDC_backbufferPallete = _WinAPI_CreateCompatibleDC($hDCPallete)
Global Const $DC_objPallete = _WinAPI_SelectObject($hDC_backbufferPallete, $hHBitmapPallete)
Global Const $hBackbufferPallete = _GDIPlus_GraphicsCreateFromHDC($hDC_backbufferPallete)
Global $hBrushPallete = _GDIPlus_BrushCreateSolid(0xFF000000)
;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing)
_GUIPallete_Update()
_GUIPallete_Reset()
#EndRegion - Pallete Mixer GUI
#Region - Plasma Editor GUI
Global $aGUIPlasmaEditor[1] = ["id|hWnd"]
Global Enum $hGUIPlasmaEditor = 1, $idCmbPlasmaSelector, $idCmbPlasmaDisplay, $idBtnPlasmaAdd, $idBtnPlasmaDel, $idCmbPlasmaShape, $idSliderPlasmaSpread, $idCmbPlasmaSpread, $idSliderPlasmaRotation, $idCmbPlasmaRotation, $idSliderPlasmaPosition, $idCmbPlasmaPosition, $iGUIPlasmaEditorLast
ReDim $aGUIPlasmaEditor[$iGUIPlasmaEditorLast]

$aGUIPlasmaEditor[$hGUIPlasmaEditor] = GUICreate("Plasma Editor", 419, 323, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIPlasmaEditor_Hide")
GUICtrlCreateLabel("Display", 16, 8, 95, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$aGUIPlasmaEditor[$idCmbPlasmaDisplay] = GUICtrlCreateCombo("", 16, 24, 121, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "All Combined|Selected Plasma", "All Combined")
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaDisplay")
GUICtrlCreateLabel("Selected Plasma", 24, 96, 120, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$aGUIPlasmaEditor[$idBtnPlasmaAdd] = GUICtrlCreateButton("Add Plasma", 160, 16, 113, 33)
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaAddRem")
GUICtrlSetState(-1, $GUI_DISABLE)
$aGUIPlasmaEditor[$idBtnPlasmaDel] = GUICtrlCreateButton("Remove Plasma", 296, 16, 113, 33)
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaAddRem")
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlCreateGroup("Plasma Controls", 8, 64, 401, 249)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$aGUIPlasmaEditor[$idCmbPlasmaSelector] = GUICtrlCreateCombo("", 24, 112, 121, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Plasma #1|Plasma #2|Plasma #3|Plasma #4", "Plasma #1")
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSelect")
GUICtrlCreateLabel("Shape", 174, 96, 35, 17)
$aGUIPlasmaEditor[$idCmbPlasmaShape] = GUICtrlCreateCombo("", 174, 112, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Horizontal|Vertical|Diagonal|Circular", "Horizontal")
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetShape")
GUICtrlCreateLabel("Spread", 24, 145, 38, 17)
$aGUIPlasmaEditor[$idSliderPlasmaSpread] = GUICtrlCreateSlider(16, 160, 257, 25, $TBS_FIXEDLENGTH)
GUICtrlSetLimit(-1, 255, 5)
$aGUIPlasmaEditor[$idCmbPlasmaSpread] = GUICtrlCreateCombo("", 280, 160, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Static|Oscillate", "Static")
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetSpread")
GUICtrlCreateLabel("Rotation", 24, 201, 44, 17)
GUICtrlSetState(-1, $GUI_DISABLE)
$aGUIPlasmaEditor[$idSliderPlasmaRotation] = GUICtrlCreateSlider(16, 216, 257, 25, $TBS_FIXEDLENGTH)
GUICtrlSetState(-1, $GUI_DISABLE)
$aGUIPlasmaEditor[$idCmbPlasmaRotation] = GUICtrlCreateCombo("", 280, 216, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Static|Oscillate", "Static")
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetRotation")
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlCreateLabel("Position", 24, 257, 41, 17)
GUICtrlSetState(-1, $GUI_DISABLE)
$aGUIPlasmaEditor[$idSliderPlasmaPosition] = GUICtrlCreateSlider(16, 272, 257, 25, $TBS_FIXEDLENGTH)
GUICtrlSetLimit(-1, 127, -127)
GUICtrlSetState(-1, $GUI_DISABLE)
$aGUIPlasmaEditor[$idCmbPlasmaPosition] = GUICtrlCreateCombo("", 280, 272, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Static|Oscillate", "Static")
GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetPosition")
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlCreateGroup("", -99, -99, 1, 1)

_GUIPlasmaEditor_PlasmaSettingsLoad($iSelectPlasma)
;_GUIPlasmaEditor_PlasmaControlsLock()
GUISetAccelerators($aAccelKeys)
#EndRegion - Plasma Editor GUI
#Region - Initialization and Main Loop
GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO")
GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

GUISetState(@SW_SHOW, $aGUI[$hGUI])

While 1
    If $bIsPlaying And Not $bIsDrawing Then _DrawScreen(_RenderPlasma())
    Sleep(10)
WEnd
#EndRegion - Initialization and Main Loop
#Region - Main GUI Functions
Func _DrawScreen($aPixels)
    ;If Function called while Drawing Return 0
    If $bIsDrawing Then Return 0
    ;Set Drawing Status Indictaor
    $bIsDrawing = True
    ;Create Timer for Drawing Performance/Duration
    Local $hTimer = TimerInit()
    ;Erase Bitmap Graphic
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF)
    ;Capture Client Window Size
    $aWinClientSize = WinGetClientSize($aGUI[$hGUI])
    ;Setup Variables
    Local $iPixelIndex = 0
    Local $iCol = $iCols
    Local $iRow = $iRows
    Local $iWidth = $aWinClientSize[0] / $iCol
    Local $iHeight = $aWinClientSize[1] / $iRow
    ;Draw Pixel Grid (Top-Left to Bottom Right)
    For $iY = 0 To $iRow - 1
        For $iX = 0 To $iCol - 1
            Local $dARGB = $aPixels[$iPixelIndex]
            ;Set Brush Color
            _GDIPlus_BrushSetSolidColor($hBrush, $dARGB)
            ;Draw "Pixel"
            _GDIPlus_GraphicsFillRect($hBackbuffer, $iX * $iWidth, $iY * $iHeight, $iWidth, $iHeight, $hBrush)
            ;Increment Pixel Counter
            $iPixelIndex += 1
            If $iPixelIndex = UBound($aPixels) Then $iPixelIndex = 0
        Next
    Next
    ;Draw Bitmap to Screen
    _WinAPI_BitBlt($hDC, 0, 0, $aWinClientSize[0], $aWinClientSize[1], $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI
    ;FPS Counter
    $hTimer = TimerDiff($hTimer)
;~  ConsoleWrite("Whole Process time: " & Round($hTimer / 1000, 3) & @CRLF)
    If $bIsPlaying Then
        If TimerDiff($hTimerFPS) >= 998 Then
            Local $iFPS = Round(1000 / $hTimer, 2)
            WinSetTitle($aGUI[$hGUI], "", $sTitle & "  (" & $iFPS & " FPS)  " & $iCols & " x " & $iRows)
            $hTimerFPS = TimerInit()
        EndIf
    Else
        ;Show FPS in Window Title
        WinSetTitle($aGUI[$hGUI], "", $sTitle)
    EndIf
    $bIsDrawing = False
EndFunc   ;==>_DrawScreen

Func _Exit()
    ; Clean up resources
    _GUIPallete_Exit()
    GUIDelete($aGUIPallete[$hGUIPallete])
    GUIDelete($aGUIPlasmaEditor[$hGUIPlasmaEditor])
    GUIDelete($aGUI[$hGUI])
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _WinAPI_SelectObject($hDC, $DC_obj)
    _WinAPI_DeleteObject($hHBitmap)
    _WinAPI_ReleaseDC($hGUI, $hDC)
    _GDIPlus_Shutdown()
    DllClose($hDLL)
    Exit
EndFunc   ;==>_Exit

Func _PlayToggle()
    ;Toggle Play State
    If Not $bIsPlaying Then
        ;Start Playing
        $bIsPlaying = True
        $hTimerFPS = TimerInit()
        GUICtrlSetData($aGUI[$idMnuFilePlay], "&Pause")
    Else
        ;Stop Playing
        $bIsPlaying = False
        GUICtrlSetData($aGUI[$idMnuFilePlay], "&Play")
    EndIf
EndFunc   ;==>_PlayToggle

Func _RenderPlasma()
    ;Setup Variables
    Local $aWorkPallete = $aPallete
    Local $iRow = $iRows
    Local $iCol = $iCols
    Local $iGridSize = $iRow * $iCol
    Local $aPixels[$iGridSize]
    Local $iIndex = 0
    Local $iPlasma = 0
    Local $iPlasmas
    Local $iDisplayPlasmaNumber = $iDisplayPlasma
    Local $iSine, $iSpread, $iPosition
    ;Loop Through Pixel Grid and Calculate Plasma(s)
    For $iY = 0 To $iRow - 1
        For $iX = 0 To $iCol - 1
            $iPlasmas = 0
            If Not $iDisplayPlasmaNumber Then
                For $iZ = 0 To UBound($aPlasmas) - 1
                    $iSine = $aPlasmas[$iZ][0]
                    ;Spread Motions
                    If $aPlasmas[$iZ][4] Then
                        $aPlasmas[$iZ][4] += ($aPlasmas[$iZ][1] * 0.00001125)
                        $iSpread = -7*Sin($aPlasmas[$iZ][4])+9
                    Else
                        $iSpread = $aPlasmas[$iZ][1]
                    EndIf
                    $iPosition = $aPlasmas[$iZ][2]
                    $iPlasma = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$iSine] & " / " & $iSpread & "))")
                    $iPlasmas += $iPlasma
                Next
            Else
                $iSine = $aPlasmas[$iDisplayPlasmaNumber - 1][0]
                ;Spread Motions
                If $aPlasmas[$iDisplayPlasmaNumber - 1][4] Then
                    $aPlasmas[$iDisplayPlasmaNumber - 1][4] += ($aPlasmas[$iDisplayPlasmaNumber - 1][1] * 0.005)
                    $iSpread = Sin($aPlasmas[$iDisplayPlasmaNumber - 1][4])/2
                Else
                    $iSpread = $aPlasmas[$iDisplayPlasmaNumber - 1][1]
                EndIf
                $iPosition = $aPlasmas[$iDisplayPlasmaNumber - 1][2]
                ;$iPlasmas = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$aPlasmas[$iDisplayPlasmaNumber - 1][0]] & " / " & $aPlasmas[$iDisplayPlasmaNumber - 1][1] & ") - " & $aPlasmas[$iDisplayPlasmaNumber - 1][2] & ")")
                $iPlasmas = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$iSine] & " / " & $iSpread & "))")
            EndIf
            $iPlasma = Int($iPlasmas)
            ;Account for Pallete Shift
            $iPlasma += $iPalleteShift
            ;Wrap Pixel Pallete Color
            If $iPlasma >= 256 Then
                Do
                    $iPlasma -= 256
                Until $iPlasma < 256
            EndIf
            If $iPlasma <= -1 Then
                Do
                    $iPlasma += 256
                Until $iPlasma > -1
            EndIf
            ;Set Pixel Color value from Pallete
            $aPixels[$iIndex] = $aWorkPallete[$iPlasma]
            ;Increment Pixel Index Counter
            $iIndex += 1
            If $iIndex = $iGridSize Then $iIndex = 0
        Next
    Next
    ;Pallete Shift Logic
    If $bPalleteShift Then
        $iPalleteShift += $iPalletShiftDirection
        If $iPalleteShift >= 256 Then $iPalleteShift = 0
        If $iPalleteShift <= -1 Then $iPalleteShift = 255
    EndIf

    Return $aPixels
EndFunc   ;==>_RenderPlasma

Func _WM_GETMINMAXINFO($hwnd, $Msg, $wParam, $lParam)
    ;Only Control Size of Main GUI
    If $hwnd <> $aGUI[$hGUI] Then Return Default
    $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($tagMaxinfo, 7, $iWinMinWidth) ; min X
    DllStructSetData($tagMaxinfo, 8, $iWinMinHeight) ; min Y
    Return 0
EndFunc   ;==>_WM_GETMINMAXINFO

Func _WM_NOTIFY($hwnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    ;Local $tInfo
    If Not _IsPressed("01", $hDLL) Then Return Default

    Switch $iIDFrom
        Case $aGUIPallete[$idSliderRPosition]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(0, -1, GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderRValue]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(0, GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderRSpread]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(0, -1, "", GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderGPosition]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(1, -1, GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderGValue]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(1, GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderGSpread]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(1, -1, "", GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderBPosition]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(2, -1, GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderBValue]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(2, GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPallete[$idSliderBSpread]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    _GUIPallete_ColorSet(2, -1, "", GUICtrlRead($iIDFrom))
            EndSwitch
            Return 0
        Case $aGUIPlasmaEditor[$idSliderPlasmaSpread]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    $aPlasmas[$iSelectPlasma][1] = 0.2 * GUICtrlRead($iIDFrom)
            EndSwitch
            Return 0
        Case $aGUIPlasmaEditor[$idSliderPlasmaRotation]
            Switch $iCode
                Case $NM_CUSTOMDRAW

            EndSwitch
            Return 0
        Case $aGUIPlasmaEditor[$idSliderPlasmaPosition]
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    $aPlasmas[$iSelectPlasma - 1][2] = GUICtrlRead($iIDFrom)
            EndSwitch
            Return 0
    EndSwitch

    Return 0
EndFunc   ;==>_WM_NOTIFY

Func _Zoom()
    Local $bPlaying = $bIsPlaying
    If $bPlaying Then $bIsPlaying = False
    Local $iCtrlID = @GUI_CtrlId
    Switch $iCtrlID
        Case $aGUI[$idMnuOptionsZoomOut]
            $iCols += 2
            $iRows += 2
            If $iCols >= 4 * 8 Then $iCols = 4 * 8
            If $iRows >= 4 * 8 Then $iRows = 4 * 8
        Case $aGUI[$idMnuOptionsZoomIn]
            $iCols -= 2
            $iRows -= 2
            If $iCols <= 4 Then $iCols = 4
            If $iRows <= 4 Then $iRows = 4
    EndSwitch
    If $bPlaying Then $bIsPlaying = $bPlaying
EndFunc   ;==>_Zoom
#EndRegion - Main GUI Functions
#Region - Pallete Mixer GUI Functions
Func _GUIPallete_ColorSet($iColor, $iValue = -1, $iPosition = "", $iSpread = "")
    If $iValue >= 0 Then $aPalleteSettings[$iColor][2] = (128.0 - $iValue)
    If $iPosition Then $aPalleteSettings[$iColor][0] = (0.25 * $iPosition)
    If $iSpread Then $aPalleteSettings[$iColor][1] = ($iSpread ^ 2)
    Return _GUIPallete_Update()
EndFunc   ;==>_GUIPallete_ColorSet

Func _GUIPallete_Draw()
    ;Draw Color Pallete in Palette Mixer GUI
    _GDIPlus_GraphicsClear($hBackbufferPallete, 0xFF000000)
    Local $iX = 0
    For $iColor = 1 To 256
        Local $dARGB = $aPallete[$iColor - 1]
        ;Set Brush Color
        _GDIPlus_BrushSetSolidColor($hBrushPallete, $dARGB)
        ;Draw Color Bar to Bitmap
        _GDIPlus_GraphicsFillRect($hBackbufferPallete, $iX, 0, 320 / 256, 40, $hBrushPallete)
        $iX += (320 / 256)
    Next
    ;Write Bitmap to Screen
    Return _WinAPI_BitBlt($hDCPallete, 8, 8, 320, 40, $hDC_backbufferPallete, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI
EndFunc   ;==>_GUIPallete_Draw

Func _GUIPallete_Exit()
    ; Clean up resources
    GUIDelete()
    _GDIPlus_BrushDispose($hBrushPallete)
    _GDIPlus_GraphicsDispose($hBackbufferPallete)
    _WinAPI_SelectObject($hDCPallete, $DC_objPallete)
    _WinAPI_DeleteObject($hHBitmapPallete)
    _WinAPI_ReleaseDC($aGUIPallete[$hGUIPallete], $hDCPallete)
    Return 1
EndFunc   ;==>_GUIPallete_Exit

Func _GUIPallete_Hide()
    Return GUISetState(@SW_HIDE, $aGUIPallete[$hGUIPallete])
EndFunc   ;==>_GUIPallete_Hide

Func _GUIPallete_Reset()
    $aPalleteSettings = $aPalleteDefaults
    GUICtrlSetData($aGUIPallete[$idSliderRPosition], $aPalleteSettings[0][0] / 0.25)
    GUICtrlSetData($aGUIPallete[$idSliderRValue], 128 - $aPalleteSettings[0][2])
    GUICtrlSetData($aGUIPallete[$idSliderRSpread], Sqrt($aPalleteSettings[0][1]))
    GUICtrlSetData($aGUIPallete[$idSliderGPosition], $aPalleteSettings[1][0] / 0.25)
    GUICtrlSetData($aGUIPallete[$idSliderGValue], 128 - $aPalleteSettings[1][2])
    GUICtrlSetData($aGUIPallete[$idSliderGSpread], Sqrt($aPalleteSettings[1][1]))
    GUICtrlSetData($aGUIPallete[$idSliderBPosition], $aPalleteSettings[2][0] / 0.25)
    GUICtrlSetData($aGUIPallete[$idSliderBValue], 128 - $aPalleteSettings[2][2])
    GUICtrlSetData($aGUIPallete[$idSliderBSpread], Sqrt($aPalleteSettings[2][1]))
    Return _GUIPallete_Update()
EndFunc   ;==>_GUIPallete_Reset

Func _GUIPallete_ShiftToggle()
    ;Toggle Pallete Shift
    Local $iCtrlState = GUICtrlRead(@GUI_CtrlId)
    If BitAND($iCtrlState, $GUI_CHECKED) Then
        ;Disable PalleteShift
        $bPalleteShift = False
        GUICtrlSetState(@GUI_CtrlId, $GUI_UNCHECKED)
    Else
        ;Enable PalleteShift
        $bPalleteShift = True
        GUICtrlSetState(@GUI_CtrlId, $GUI_CHECKED)
    EndIf
EndFunc   ;==>_GUIPallete_ShiftToggle

Func _GUIPallete_Show()
    GUISetState(@SW_SHOW, $aGUIPallete[$hGUIPallete])
    _GUIPallete_Draw()
EndFunc   ;==>_GUIPallete_Show

Func _GUIPallete_Update()
    ;Re-Calculate Work Color Pallete
    For $iStep = 0 To 255
        Local $iR = Int($aPalleteSettings[0][2] + ($aPalleteSettings[0][2] * Sin((3.1415 * $iStep / $aPalleteSettings[0][1]) - $aPalleteSettings[0][0])))
        Local $iG = Int($aPalleteSettings[1][2] + ($aPalleteSettings[1][2] * Sin((3.1415 * $iStep / $aPalleteSettings[1][1]) - $aPalleteSettings[1][0])))
        Local $iB = Int($aPalleteSettings[2][2] + ($aPalleteSettings[2][2] * Sin((3.1415 * $iStep / $aPalleteSettings[2][1]) - $aPalleteSettings[2][0])))
        $aPallete[$iStep] = "0xFF" & Hex($iR, 2) & Hex($iG, 2) & Hex($iB, 2)
    Next
    Return _GUIPallete_Draw()
EndFunc   ;==>_GUIPallete_Update
#EndRegion - Pallete Mixer GUI Functions
#Region - Plasma Editor GUI Functions
Func _GUIPlasmaEditor_Hide()
    GUISetState(@SW_HIDE, $aGUIPlasmaEditor[$hGUIPlasmaEditor])
EndFunc   ;==>_GUIPlasmaEditor_Hide

Func _GUIPlasmaEditor_PlasmaAddRem()

EndFunc   ;==>_GUIPlasmaEditor_PlasmaAddRem

Func _GUIPlasmaEditor_PlasmaDisplay()
    Local $sSelection = GUICtrlRead($aGUIPlasmaEditor[$idCmbPlasmaDisplay])
    If $sSelection = "All Combined" Then
        $iDisplayPlasma = 0
    Else
        $iDisplayPlasma = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSelector])+1
    EndIf
    Return $iDisplayPlasma
EndFunc   ;==>_GUIPlasmaEditor_PlasmaDisplay

Func _GUIPlasmaEditor_PlasmaSelect()
    Local $sSelection = GUICtrlRead($aGUIPlasmaEditor[$idCmbPlasmaSelector])
    $iSelectPlasma = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSelector])
    _GUIPlasmaEditor_PlasmaDisplay()
    Return _GUIPlasmaEditor_PlasmaSettingsLoad($iSelectPlasma)
EndFunc   ;==>_GUIPlasmaEditor_PlasmaSelect

Func _GUIPlasmaEditor_PlasmaSetPosition()

EndFunc   ;==>_GUIPlasmaEditor_PlasmaSetPosition

Func _GUIPlasmaEditor_PlasmaSetRotation()

EndFunc   ;==>_GUIPlasmaEditor_PlasmaSetRotation

Func _GUIPlasmaEditor_PlasmaSetShape()
    $aPlasmas[$iSelectPlasma][0] = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaShape])
EndFunc   ;==>_GUIPlasmaEditor_PlasmaSetShape

Func _GUIPlasmaEditor_PlasmaSetSpread()
    $aPlasmas[$iSelectPlasma][4] = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread])
EndFunc   ;==>_GUIPlasmaEditor_PlasmaSetSpread

Func _GUIPlasmaEditor_PlasmaSettingsLoad(ByRef $iPlasma)
    GUICtrlSetData($aGUIPlasmaEditor[$idSliderPlasmaSpread],$aPlasmas[$iPlasma][1]/0.2)
    _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaShape],$aPlasmas[$iPlasma][0])
    If $aPlasmas[$iPlasma][4] Then
        _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread],1)
    Else
        _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread],0)
    EndIf
    Return 1
EndFunc   ;==>_GUIPlasmaEditor_PlasmaSettingsLoad

Func _GUIPlasmaEditor_Show()
    GUISetState(@SW_SHOW, $aGUIPlasmaEditor[$hGUIPlasmaEditor])
EndFunc   ;==>_GUIPlasmaEditor_Show
#EndRegion - Plasma Editor GUI Functions

edit: Minor tweaks

Edited by spudw2k
2 people like this

Share this post


Link to post
Share on other sites



Looks cool.
It works slow in hgih resolution
I am not surprised, this is probably because Autoit is slow.
Anything related to image processing should not be done in Autoit unless you do it for fun..

This is the first time that I see code that written like my suggestion

Share this post


Link to post
Share on other sites

Thanks.  Yes, unfortunately higher res is much slower. I was considering porting my script at some point to VS2015, but that's going to be a bit of a learning curve for me.

I usually only use "Regions" when my scripts grow very big. I find them useful for organizing code as well.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I added the ASM code _ASM_DrawRectFilled  to speedup a little bit the draw function:

;coded by UEZ build 2016-02-12
#pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico")
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/so /pe /rm
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"

#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit, $pBitmap, $hHBitmap
Global Const $iW = 384, $iH = 256, $sTitle = "GDI+ Plasma v5"
Global Const $fPi = ACos(-1)
AutoItSetOption("GUIOnEventMode", 1)

GDIPlus_Plasmav5()

AutoItSetOption("GUIOnEventMode", 0)
_GDIPlus_Shutdown()


Func GDIPlus_Plasmav5()
    $bExit = False
    $hGUI = GUICreate($sTitle, $iW, $iH)
    GUISetState(@SW_SHOW, $hGUI)

    ;create canvas elements
    Local Const $hDC = _WinAPI_GetDC($hGUI)
    Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
    Local Const $hHBitmap = _WinAPI_BitmapCreateDIB($iW, $iH, $pBitmap)
    Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
    Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
;~  _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)

    Local Const $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xF0101010), _
                $hFormat_FPS = _GDIPlus_StringFormatCreate(), _
                $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _
                $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _
                $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 60, 16)

    $iFPS = 0
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About")

    Local $fTime = 0, $iSizeW = 8, $iSizeH = 8, $cx, $cy, $v, $iX, $iY, $f1, $iColor

    Local $tCodeBuffer = DllStructCreate("byte ASM[192]") ;reserve memory for ASM opcodes
    $tCodeBuffer.ASM = "0x8B7424048B7C2408558B6F1831C08B078985A800000083ADA8000000018B47048985AC00000083ADAC000000018B47088985B00000008B470C8985B40000008B47108985B80000008B47148985BC000000E8020000005DC3505351528B9DB00000008B8DB800000031C00385AC0000000385B4000000F7A5BC0000000385B00000000385A8000000890C8683ADB00000000177D4899DB000000083ADB40000000175C55A595B58C3000000000000000000000000000000000000000000000000" ;write opcodes into memory (struct) / length: 192
    Local $tRect = DllStructCreate("dword iPosX;dword iPosY;dword iW; dword iH;dword ARGB;dword iWidth;dword iBase")
    $tRect.iW = $iSizeW
    $tRect.iH = $iSizeH
    $tRect.iWidth = $iW
    $tRect.iBase = DllStructGetPtr($tCodeBuffer) ;pointer to asm code in the memory

    AdlibRegister("CalcFPS", 1000)

    Do
        For $iY = 0 To $iH - $iSizeH Step $iSizeH
            For $iX = 0 To $iW - $iSizeW Step $iSizeW

                $cx = $iX + 128 * Sin(Dist($fTime * 1.5, $iX, $iY, 32) / 48)
                $cy = $iY + 92 * Cos(Dist($iY, 128, $fTime * 2.5, 8) / 32)
                $v = Cos(Sqrt($cx * $cx + $cy * $cy) / 512 + $fTime)

                $f1 = $v * $fPi
                $tRect.ARGB = 0xFF000000 + _
                              BitShift((Abs(Cos($f1 / 2)) * 0xFF), -16) + _
                              BitShift((Abs(Sin($f1 * 2)) * 0xFF), -8) + _
                              Int(Abs(Cos($f1 / 1.5)) * 0xFF)

                $tRect.iPosX = $iX
                $tRect.iPosY = $iY

                DllCallAddress("uint:cdecl", $tRect.iBase, "ptr", $pBitmap, "struct*", $tRect)

                $fTime += 0.0000075

            Next
        Next

        _GDIPlus_GraphicsDrawStringEx($hCanvas, "FPS: " & $iShowFPS, $hFont_FPS, $tLayout_FPS, $hFormat_FPS, $hBrush_FPS)
        _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY)

        $iFPS += 1
        If $bExit Then ExitLoop
    Until Not Sleep(10)

    AdlibUnRegister("CalcFPS")
    ;release resources
    _GDIPlus_FontDispose($hFont_FPS)
    _GDIPlus_FontFamilyDispose($hFamily_FPS)
    _GDIPlus_StringFormatDispose($hFormat_FPS)
    _GDIPlus_BrushDispose($hBrush_FPS)
    _GDIPlus_GraphicsDispose($hCanvas)
    _WinAPI_SelectObject($hDC, $DC_obj)
    _WinAPI_DeleteObject($hHBitmap)
    _WinAPI_ReleaseDC($hGUI, $hDC)
    GUIDelete($hGUI)
EndFunc   ;==>GDIPlus_Plasmav5

Func Dist($a, $b, $c, $d)
    Return Sqrt(($a - $c) * ($a - $c) + ($b - $d) * ($b - $d))
EndFunc

Func _Exit_About()
    $bExit = True
EndFunc   ;==>_Exit_About

Func CalcFPS() ;display FPS
    $iShowFPS = $iFPS
    $iFPS = 0
EndFunc   ;==>CalcFPS

Func _WinAPI_BitmapCreateDIB($iWidth, $iHeight, ByRef $pHBitmap)
    Local $tBMI = DllStructCreate($tagBITMAPINFO)
    $tBMI.biSize = DllStructGetSize($tBMI) - 4
    $tBMI.biWidth = $iWidth
    $tBMI.biHeight = -$iHeight
    $tBMI.biPlanes = 1
    $tBMI.biBitCount = 32
    Local $aResult = DllCall("gdi32.dll", "ptr", "CreateDIBSection", "hwnd", 0, "struct*", $tBMI, "uint", 0, "ptr*", 0, "ptr", 0, "uint", 0)
    $pHBitmap = $aResult[4]
    Return $aResult[0]
EndFunc

 

8x8 px @384x256: without ASM ~ 7 fps, with ASM ~13 fps.

 

Might be useful for you.

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

On 2/12/2016 at 0:09 PM, UEZ said:

I added the ASM code _ASM_DrawRectFilled  to speedup a little bit the draw function:
...
Might be useful for you.

Last week I got around to checking out some of your examples and stumbled across the ASM examples including the  _ASM_DrawRectFilled func.  I was curious what impact it would have on my script.  I'll have to give it a shot. ;)

Edited by spudw2k

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Try to make this:

 

 

I didn't I imagined and expected that is the best game that included in Windows is the Magnifier tool.
it is very fun game.

Edited by gil900

Share this post


Link to post
Share on other sites

Looks like a wind tunnel simulator. :)


2015 - Still no flying cars, instead blankets with sleeves.

Share this post


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
Sign in to follow this  
Followers 0

  • Similar Content

    • c.haslam
      By c.haslam
      In my code, the mouse wheel causes the line to move up and down. It does move down to where the picture is, but is not seen there. This can be observed by scrolling down to the picture, and then up again: the line reappears as expected.
      How can I get the line to show on the picture? This seems to be a matter of transparency, but I have not found a way of getting the background of $graphLine to be transparent.
      The code is now:
      #include <ButtonConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Opt('MustDeclareVars',1) Global Const $MK_SHIFT = 0x4 Global Const $MK_CONTROL = 0x8 GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") Global $gY0,$gY1,$gForm1,$glblLine,$glblPic main() Func main() $gForm1 = GUICreate("Form1", 623, 601, 192, 114) $glblLine = GUICtrlCreateLabel("", 8, 8, 604, 137) $glblPic = GUICtrlCreateLabel("", 8, 8, 589, 500) Local $btn = GUICtrlCreateButton("Rotate", 472, 560, 65, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Local $oldY0,$oldY1 _GDIPlus_Startup() Local $h = GUICtrlGetHandle($glblLine) ; limit graphics to area of $label Local $GraphicLine = _GDIPlus_GraphicsCreateFromHWND($h) Local $hPen = _GDIPlus_PenCreate(0xFF000000,2) Local $image = _GDIPlus_ImageLoadFromFile('H:\a\P5130021.jpg') Local $h = GUICtrlGetHandle($glblPic) Local $GraphicPic = _GDIPlus_GraphicsCreateFromHWND($h) _GDIPlus_GraphicsDrawImage($GraphicPic,$image,0,0) $gY0 = 67 $gY1 = 67 _GDIPlus_GraphicsClear($GraphicLine,0) _GDIPlus_GraphicsDrawLine($GraphicLine, 10, $gY0, 350, $gY1, $hPen) ; Loop until the user exits. While True If $gY0<>$oldY0 Or $gY1<>$oldY1 Then _GDIPlus_GraphicsClear($GraphicLine,0xFFD4D0C8) _GDIPlus_GraphicsDrawLine($GraphicLine, 10, $gY0, 590, $gY1, $hPen) $oldY0 = $gY0 $oldY1 = $gY1 Else Switch GUIGetMsg() Case $GUI_EVENT_CLOSE,$btn Exit EndSwitch EndIf WEnd ; Clean up resources _GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($GraphicLine) _GDIPlus_Shutdown() EndFunc Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local Const $ymax=500 Local $vec = GUIGetCursorInfo($gForm1) If $vec[4] = $glblLine Or $vec[4]=$glblPic Then Local $iDelta = BitShift($wParam, 16) ; positive = up Local $iKeys = _WinAPI_LoWord($wParam) If BitAND($iKeys,$MK_CONTROL)=$MK_CONTROL Then If BitAND($iKeys,$MK_SHIFT)=$MK_SHIFT Then ; do nothing Else If $iDelta > 0 And $gY0>3 Then $gY0 -= 1 If $iDelta < 0 And $gY0<$ymax Then $gY0 += 1 EndIf Else If BitAND($iKeys,$MK_SHIFT)=$MK_SHIFT Then If $iDelta > 0 And $gY1>3 Then $gY1 -= 1 If $iDelta < 0 And $gY1<$ymax Then $gY1 += 1 Else If $iDelta > 0 And $gY0>3 Then $gY0 -= 1 If $iDelta < 0 And $gY0<$ymax Then $gY0 += 1 If $iDelta > 0 And $gY1>3 Then $gY1 -= 1 If $iDelta < 0 And $gY1<$ymax Then $gY1 += 1 EndIf EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOUSEWHEEL Some other questions:
      Do I really need GDI+, or is there a simpler way? My code creates Graphics (canvases?) from labels. Is this legitimate? I have found MSDN to be un-helpful in learning GDI+. Is there a better learning tool?
    • timmalos
      By timmalos
      Hey all.
      I'm trying to know when my user clicks on a Rect drawn via GDI+. Everything is almost working except I have a strange behaviour in the "order" clicks are fired.
      I created a simplified code to help :
      #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <Array.au3> Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled _GDIPlus_Startup() Global $hGUI, $hGraphics Global $iWidth = 1024, $iHeight = 762 createGUI() draw() While 1 Sleep(10) WEnd Func createGUI() $hGUI = GUICreate("Current CasparCG Output", $iWidth,$iHeight) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetBkColor(0x000000) GUISetState(@SW_SHOW) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;sets the graphics object rendering quality (antialiasing) EndFunc ;==>Example Func draw() ;_WinAPI_draw($hGUI,"","",BitOR($RDW_ERASE,$RDW_INVALIDATE,$RDW_UPDATENOW)) _GDIPlus_GraphicsClear($hGraphics) $hFamily = _GDIPlus_FontFamilyCreate("Arial") $hFont = _GDIPlus_FontCreate($hFamily, 15, 1) $hPen = _GDIPlus_PenCreate(0xFFFEDCFF, 2) ;color format AARRGGBB (hex) $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) $hBrushString = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF00FF) ;color format AARRGGBB (hex) For $i = 1 to 2 Local $x = 0.25 Local $y = 0.25 Local $w = 0.5 Local $h = 0.5 Local $title = "Layer "&$i If $x >= -1 And $x <= 1 Then $x *= $iWidth If $y >= -1 And $y <= 1 Then $y *= $iHeight If $w >= -1 And $w <= 1 Then $w *= $iWidth If $h >= -1 And $h <= 1 Then $h *= $iHeight $hItem = GUICtrlCreateLabel("", $x,$y,$w,$h) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetOnEvent($hItem,"_gui_layer_clicked") ConsoleWrite("Created label with handle="&$hItem&" $i= " & $i&@CRLF) _GDIPlus_GraphicsFillRect($hGraphics, $x, $y, $w, $h,$hBrush) _GDIPlus_GraphicsDrawRect($hGraphics, $x, $y, $w, $h,$hPen) $tLayout = _GDIPlus_RectFCreate($x, $y, $w, $h) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $title, $hFont, $tLayout, $hFormat) _GDIPlus_GraphicsDrawStringEx($hGraphics, $title, $hFont, $aInfo[0], $hFormat, $hBrushString) Next _GDIPlus_BrushDispose($hBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_FontDispose($hFont) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrushString) Return 1 EndFunc Func _gui_layer_clicked() ConsoleWrite("Clicked on " & @GUI_CtrlId&@CRLF) EndFunc Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Clean up resources _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() Exit EndSelect EndFunc ;==>SpecialEvents What happens there :
      We have two rectangles, with the one labelled "2" is front and, the one labelled "1" in background. However when we click, the fired label is the one created first (in the background) and not the second one (in the front).
      Is it normal ?
      If yes, is there any way to change this order ? If I create another label after a first one on the same coords, I would the second one to be fired instead of the first one (This is a simplified code I can't just invert the label order creation easily)
       
      Thanks for your help
       
    • InunoTaishou
      By InunoTaishou
      Struggling a bit to get this GDI+ function converted to AutoIt.
      #include <GDIPlus.au3> _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile("F:\DCIM\Camera\20170515_111804.jpg") Global $tBufferSize = DllStructCreate("uint") Global $tProperties = DllStructCreate("uint") _GDIPlus_GetPropertySize($hImage, $tBufferSize, $tProperties) Global $tAllItems = DllStructCreate("struct;char[" & DllStructGetData($tBufferSize, 1) & "];endstruct") _GDIPlus_GetAllPropertyItems($hImage, $tBufferSize, $tProperties, $tPropertyItem) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Func _GDIPlus_GetAllPropertyItems(ByRef $hImage, Const $tTotalBufferSize, Const $tNumProperties, ByRef $tAllItems) If (Not IsDllStruct($tPropertyItem)) Then Return SetError(-1, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetAllPropertyItems", "hwnd", $hImage, "unit", DllStructGetData($tTotalBufferSize, 1), "uint", DllStructGetData($tNumProperties, 1), "ptr", DllStructGetPtr($tAllItems)) If (@error) Then Return SetError(@error, @extended, ConsoleWrite("@Error = " & @error & @LF)) If ($aResult[0]) Then Return SetError($aResult[0], @extended, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetAllPropertyItems Func _GDIPlus_GetPropertySize(Const ByRef $hImage, ByRef $tTotalBufferSize, ByRef $tNumProperties) If (Not IsDllStruct($tTotalBufferSize)) Then Return SetError(-1, 0, "") If (Not IsDllStruct($tNumProperties)) Then Return SetError(-2, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint_ptr", DllStructGetPtr($tTotalBufferSize), "uint_ptr", DllStructGetPtr($tNumProperties)) If (@error) Then Return SetError(@error, @extended, "") If ($aResult[0]) Then Return SetError($aResult[0], 0, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetPropertySize Got the GetPropertySize function to work, gives me the correct buffer size and the property count, but I cannot figure out how to get the struct for the all items.
      Function on MSDN:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms535372(v=vs.85).aspx
      Struct needed:
      PropertyItem class:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx
      Found other topics about this function in other languages where they used a blank string as the buffer, so I tried using a char array, which doesn't work. Just cannot figure out how to create the struct buffer to hold the data.
    • UEZ
      By UEZ
      Since I disovered FreeBasic I decided to create a DLL to implement much faster image processing functionality to AutoIt.
      Following functions are implemented yet:
      _GDIPlus_BitmapApplyFilter_BWJJNDithering _GDIPlus_BitmapApplyFilter_Cartoon1 _GDIPlus_BitmapApplyFilter_ColorAccent _GDIPlus_BitmapApplyFilter_Convolution_AnotherBlur _GDIPlus_BitmapApplyFilter_Convolution_BoxBlur _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection1 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection2 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection3 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection4 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection5 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection6 _GDIPlus_BitmapApplyFilter_Convolution_Emboss1 _GDIPlus_BitmapApplyFilter_Convolution_Emboss45Degree _GDIPlus_BitmapApplyFilter_Convolution_EmbossTopLeftBottomRight _GDIPlus_BitmapApplyFilter_Convolution_Gaussian3x3 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_1 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_2 _GDIPlus_BitmapApplyFilter_Convolution_GaussianBlur _GDIPlus_BitmapApplyFilter_Convolution_IntenseEmboss _GDIPlus_BitmapApplyFilter_Convolution_Kirsch _GDIPlus_BitmapApplyFilter_Convolution_Laplace1 _GDIPlus_BitmapApplyFilter_Convolution_Laplace2 _GDIPlus_BitmapApplyFilter_Convolution_Laplace3 _GDIPlus_BitmapApplyFilter_Convolution_LaplacianOfGaussian _GDIPlus_BitmapApplyFilter_Convolution_ManualMatrix _GDIPlus_BitmapApplyFilter_Convolution_MotionBlur _GDIPlus_BitmapApplyFilter_Convolution_Outline3x3 _GDIPlus_BitmapApplyFilter_Convolution_Prewitt _GDIPlus_BitmapApplyFilter_Convolution_Sharpen1 _GDIPlus_BitmapApplyFilter_Convolution_Sharpen2 _GDIPlus_BitmapApplyFilter_Convolution_Sobel _GDIPlus_BitmapApplyFilter_Convolution_SovelVsPrewitt _GDIPlus_BitmapApplyFilter_Convolution_TriangleBlur _GDIPlus_BitmapApplyFilter_Convolution_Unsharp _GDIPlus_BitmapApplyFilter_Convolution_Unsharp5x5 _GDIPlus_BitmapApplyFilter_Dilatation _GDIPlus_BitmapApplyFilter_DistortionBlur _GDIPlus_BitmapApplyFilter_Edges _GDIPlus_BitmapApplyFilter_Erosion _GDIPlus_BitmapApplyFilter_FishEye _GDIPlus_BitmapApplyFilter_Indexed _GDIPlus_BitmapApplyFilter_Jitter _GDIPlus_BitmapApplyFilter_Kuwahara _GDIPlus_BitmapApplyFilter_Linellism _GDIPlus_BitmapApplyFilter_Median _GDIPlus_BitmapApplyFilter_Median2 _GDIPlus_BitmapApplyFilter_OilPainting _GDIPlus_BitmapApplyFilter_PenSketch _GDIPlus_BitmapApplyFilter_PenSketch2 _GDIPlus_BitmapApplyFilter_Pixelate _GDIPlus_BitmapApplyFilter_Pointillism _GDIPlus_BitmapApplyFilter_RadialBlur _GDIPlus_BitmapApplyFilter_Raster _GDIPlus_BitmapApplyFilter_Swirl _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour _GDIPlus_BitmapApplyFilter_TiltShift _GDIPlus_BitmapApplyFilter_TimeWarp _GDIPlus_BitmapApplyFilter_Wave _GDIPlus_BitmapApplyFilter_XRay  
      Since I am absolutely a newbie in FreeBasic, the DLL may contain errors.  Please report any bug.
       
      FreeBasic source code can be found here: https://pastebin.com/Lugp6rCR
       
      To do:
      add function headers with descriptions speed-up FB code -> partly done add more filters -> ongoing  
      Credits to:
      Jakub Szymanowski rdc Dewald Esterhuizen Santhosh G_  Christian Graus www.gutgames.com  
      Have fun.
       
      Download link: 
       
      You can compare the speed with AutoIt version:
      #AutoIt3Wrapper_Version=b #include <Array.au3> #include <GDIPlus.au3> Global $sFile = FileOpenDialog("Select an image", "", "Images (*.jpg;*.png;*.gif;*.bmp)") If @error Then Exit _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172 Global Const $hImage = _GDIPlus_ImageLoadFromFile($sFile) Global Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Global Const $hGUI = GUICreate("GDI+ Image Filters", $iW * 2, $iH) Global $fProg = 0, $iEnd = $iW * $iH - 1 AdlibRegister("Progress", 490) Global $t = TimerInit() Global Const $hGDIBitmap = _GDIPlus_BitmapApplyFilter_Median($hImage, 4) ConsoleWrite(Round(TimerDiff($t) / 1000, 2) & " s / " & Round(TimerDiff($t) / 60000, 2) & " min" & @CRLF) Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1) Global Const $iPic_o = GUICtrlCreatePic("", $iW, 0, $iW - 1, $iH - 1) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap)) Global Const $hGDIBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_o, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap2)) GUISetState() AdlibUnRegister("Progress") ToolTip("") Do Until GUIGetMsg() = -3 _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hGDIBitmap) _WinAPI_DeleteObject($hGDIBitmap2) _GDIPlus_Shutdown() Exit Func Progress() ToolTip(Int($fProg / $iEnd * 100) & " % / " & Round(TimerDiff($t) / 60000, 2) & " min", MouseGetPos(0) + 30, MouseGetPos(1) + 30) EndFunc #Region Symmetric Nearest Neighbour Func _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour($hImage, $fRadius = 2, $bGDI = True) ;no alpha channel implemented yet Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iRowOffset, $iX, $iY, $c, $k, $sumR, $sumG, $sumB, $iCount, $xx, $yy, $iR, $iG, $iB, $iR1, $iG1, $iB1, $iR2, $iG2, $iB2, $x, $y For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW For $iX = 0 To $iW - 1 $sumR = 0 $sumG = 0 $sumB = 0 $iCount = 0 $c = DllStructGetData($tPixel, 1, $iRowOffset + $iX) $iR = BitShift(BitAND(0x00FF0000, $c), 16) $iG = BitShift(BitAND(0x0000FF00, $c), 8) $iB = BitAND(0x000000FF, $c) For $yy = -$fRadius To $fRadius For $xx = -$fRadius To $fRadius $k = $iX + $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = $iY + $yy $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR1 = BitShift(BitAND(0x00FF0000, $c), 16) $iG1 = BitShift(BitAND(0x0000FF00, $c), 8) $iB1 = BitAND(0x000000FF, $c) $k = $iX - $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = ($iY - $yy) $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR2 = BitShift(BitAND(0x00FF0000, $c), 16) $iG2 = BitShift(BitAND(0x0000FF00, $c), 8) $iB2 = BitAND(0x000000FF, $c) If __DeltaE($iR, $iG, $iB, $iR1, $iG1, $iB1) < __DeltaE($iR, $iG, $iB, $iR2, $iG2, $iB2) Then $sumR += $iR1 $sumG += $iG1 $sumB += $iB1 Else $sumR += $iR2 $sumG += $iG2 $sumB += $iB2 EndIf $iCount += 1 Next Next DllStructSetData($tPixel_Dest, 1, 0xFF000000 + Int($sumR / $iCount) * 0x10000 + Int($sumG / $iCount) * 0x100 + Int($sumB / $iCount), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_SNN" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __DeltaE($iR1, $iG1, $iB1, $iR2, $iG2, $iB2) Return Sqrt(($iR1 - $iR2) * ($iR1 - $iR2) + ($iG1 - $iG2) * ($iG1 - $iG2) + ($iB1 - $iB2) * ($iB1 - $iB2)) EndFunc #EndRegion #Region Jitter Func _GDIPlus_BitmapApplyFilter_Jitter($hImage, $iAmount = 20, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset, $fNX, $fNY For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 $fNX = $iX + Int((Random() - 0.5) * $iAmount) $fNX = $fNX < 1 ? 1 : $fNX > $iW - 1 ? $iW - 1 : $fNX $fNY = ($iY + Int((Random() - 0.5) * $iAmount)) $fNY = $fNY < 1 ? 1 : $fNY > $iH - 1 ? $iH - 1 : $fNY $fNY *= $iW DllStructSetData($tPixel_Dest, 1, DllStructGetData($tPixel, 1, $fNY + $fNX), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Jitter" & $iAmount & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc #EndRegion #Region Median Func _GDIPlus_BitmapApplyFilter_Median($hImage, $fRadius = 3, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 DllStructSetData($tPixel_Dest, 1, __Median_Value($iX, $iY, $fRadius, $tPixel, $iW, $iH), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Median" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __Median_Value($iPosX, $iPosY, $fRadius, $tPixel, $iW, $iH) Local $iX, $iY, $aColors[1000], $iColors = 0, $iSize = $iW * $iH - 1, $iOff, $e For $iX = $iPosX - $fRadius To $iPosX + $fRadius For $iY = $iPosY - $fRadius To $iPosY + $fRadius $iOff = 1 + $iY * $iW + $iX $aColors[$iColors] = DllStructGetData($tPixel, 1, $iOff < 1 ? 1 : $iOff > $iSize ? $iSize : $iOff) $iColors += 1 Next Next ReDim $aColors[$iColors] ;~ _ArraySort($aColors, 0) $e = $iColors - 1 __ArrayQuickSort1D($aColors, 0, $e) Local $iMid = Floor($iColors / 2), $iMedian If BitAND($iColors, 1) Then $iMedian = Int($aColors[$iMid + 1]) Else $iMedian = Int(($aColors[$iMid] + $aColors[$iMid + 1]) / 2) EndIf Return $iMedian EndFunc #EndRegion  
    • InunoTaishou
      By InunoTaishou
      Take a screenshot of your desktop (works even if the desktop is hidden), then redraws it row by row. Makes a neat little effect. An effect I remember seeing at the photo booth at Chuck E' Cheese.
      I mostly just wanted to mess with LockBits and PrintWindow and thought this was a decent way to figure it out, but I liked the outcome and thought I'd share lol
      #include <GDIPlus.au3> #include <WinApi.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() Global $tDesktopMetrics = GetDesktopMetrics() Global $hHBitmapDesktop = CaptureWindow("", -1, -1, -1, -1, "Program Manager") Global $hBitmapDesktop = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmapDesktop) _WinAPI_DeleteObject($hHBitmapDesktop) Global $iW = _GDIPlus_ImageGetWidth($hBitmapDesktop) Global $iH = _GDIPlus_ImageGetHeight($hBitmapDesktop) Global $tBitmapData = _GDIPlus_BitmapLockBits($hBitmapDesktop, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32PARGB) Global $tPixelMap = DllStructCreate("int[" & $iW * $iH & "];", DllStructGetData($tBitmapData, "Scan0")) Global $hGui = GUICreate("Redraw", $iW, $iH, $tDesktopMetrics.x, $tDesktopMetrics.y, $WS_POPUP) Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui) Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Global $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32PARGB) Global $tPixelMap2 = DllStructCreate("int[" & $iW * $iH & "];", DllStructGetData($tBitmapData2, "Scan0")) GUISetState(@SW_SHOW, $hGui) _GDIPlus_GraphicsClear($hGraphics) For $iY = 0 To $iH - 1 Local $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 ;get each pixel in each line and row DllStructSetData($tPixelMap2, 1, DllStructGetData($tPixelMap, 1, $iRowOffset + $iX), $iRowOffset + $iX) Next If (Not Mod($iY, 5)) Then ; Every 5 rows draw the bitmap _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData2) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32PARGB) $tPixelMap2 = DllStructCreate("int[" & $iW * $iH & "];", DllStructGetData($tBitmapData2, "Scan0")) EndIf Next If (Mod($iY, 5)) Then ; Didn't end on an even row, clean up _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData2) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) $tPixelMap2 = 0 $tBitmapData2 = 0 EndIf _GDIPlus_BitmapUnlockBits($hBitmapDesktop, $tBitmapData) _GDIPlus_BitmapDispose($hBitmapDesktop) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() GUIDelete($hGui) Exit 0 Func CaptureWindow($sFileName = "", $iLeft = -1, $iTop = -1, $iWidth = -1, $iHeight = -1, $hWnd = WinGetHandle("[Active]"), $bClientArea = True) If (Not IsHWnd($hWnd)) Then $hWnd = WinGetHandle($hWnd) If (@error) Then Return SetError(1, 0, False) If (BitAND(WinGetState($hWnd), 16) = 16) Then Return SetError(2, 0, False) Local $iSrcWidth = 0 Local $iSrcHeight = 0 ConsoleWrite($iLeft & ', ' & $iTop & ", " & $iWidth & ', ' & $iHeight & @LF) If ($hWnd = _WinAPI_GetDesktopWindow() Or $hWnd = WinGetHandle("Program Manager")) Then Local $tDesktop = GetDesktopMetrics() If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default Or $iWidth > DllStructGetData($tDesktop, 3)) Then $iWidth = DllStructGetData($tDesktop, 3) If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default Or $iWidth > DllStructGetData($tDesktop, 4)) Then $iHeight = DllStructGetData($tDesktop, 4) $iSrcWidth = DllStructGetData($tDesktop, 3) $iSrcHeight = DllStructGetData($tDesktop, 4) Else Local $tRectWindow = _WinAPI_GetWindowRect($hWnd) ; Get the absolute width, using Abs on all of the memembers because the [1] index of the struct may be negative, supports multiple monitors Local $iAbsWidth = Abs(Abs(DllStructGetData($tRectWindow, 3)) - Abs(DllStructGetData($tRectWindow, 1))) ; Get the absolute height, using Abs on all of the memembers because the [1] index of the struct may be negative, supports multiple monitors ; Subtracts the caption bar if $bClientArea only Local $iAbsHeight = Abs(Abs(DllStructGetData($tRectWindow, 4)) - Abs(DllStructGetData($tRectWindow, 2))) - ($bClientArea ? _WinAPI_GetSystemMetrics($SM_CYCAPTION) : 0) If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default Or $iWidth > $iAbsWidth) Then $iWidth = $iAbsWidth If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default Or $iHeight > $iAbsHeight) Then $iHeight = $iAbsHeight $iSrcWidth = $iAbsWidth $iSrcHeight = $iAbsHeight EndIf If ($iLeft = -1 Or $iLeft = Default) Then $iLeft = 0 If ($iTop = -1 Or $iTop = Default) Then $iTop = 0 Local $hDC = _WinAPI_GetWindowDC($hWnd) Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC) Local $hDestBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight) Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hDestBitmap) Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBmp = _WinAPI_CreateCompatibleBitmap($hDC, $iSrcWidth, $iSrcHeight) Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBmp) _WinAPI_PrintWindow($hWnd, $hSrcDC, True) _WinAPI_BitBlt($hDestDC, 0, 0, $iWidth, $iHeight, $hSrcDC, $iLeft, $iTop, $MERGECOPY) _WinAPI_SelectObject($hDestDC, $hDestSv) _WinAPI_SelectObject($hSrcDC, $hSrcSv) _WinAPI_ReleaseDC($hWnd, $hDC) _WinAPI_DeleteDC($hDestDC) _WinAPI_DeleteDC($hSrcDC) _WinAPI_DeleteObject($hBmp) $tPoint = 0 $tRectWindow = 0 $tDesktop = 0 If ($sFileName) Then _GDIPlus_Startup() Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hDestBitmap) _GDIPlus_ImageSaveToFile($hBitmap, $sFileName) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() EndIf Return $hDestBitmap EndFunc ;==>CaptureWindow Func GetDesktopMetrics() Return _GDIPlus_RectFCreate(_WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN), _ _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)) EndFunc ;==>GetDesktopMetrics