Jump to content

GDI setpixel


 Share

Recommended Posts

*replace the 4 splashimage placeholders to run script.

I would have put this under the other GDI topic i made, but I believe this is an issue with Random() [well not 'an' issue, more the issue im having]

The randomness is always left-->right AND top-->bottom, so the last section redrawn on every picture is bottom right quadrant.

Can this behavior be altered?

#include <GUIConstants.au3>
#include <Array.au3>
#include <Misc.au3>


;======== load image into array ==============
SplashImageOn("", "G***.gif", 90, 90, 0, 0, 1)

Dim $Array[90][90]

For $B = 0 To UBound($Array, 1) - 1
    For $C = 0 To UBound($Array, 2) - 1
        $Array[$B][$C] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next

SplashImageOn("", "w***.jpg", 90, 90, 0, 0, 1)

Dim $BArray[90][90]

For $B = 0 To UBound($BArray, 1) - 1
    For $C = 0 To UBound($BArray, 2) - 1
        $BArray[$B][$C] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next


SplashImageOn("", "m***.gif", 90, 90, 0, 0, 1)

Dim $CArray[90][90]

For $B = 0 To UBound($CArray, 1) - 1
    For $C = 0 To UBound($CArray, 2) - 1
        $CArray[$B][$C] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next

SplashImageOn("", "mc***.gif", 90, 90, 0, 0, 1)

Dim $DArray[90][90]

For $B = 0 To UBound($DArray, 1) - 1
    For $C = 0 To UBound($DArray, 2) - 1
        $DArray[$B][$C] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next




;========= Draw array of pixels to desktop at mouse button down ===============
Local $aMPos, $dc

$start1 = TimerInit ()

$dif = timerdiff($start1)

While timerdiff($start1) < 10000
            Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
            For $B = 0 To Random(UBound($Array, 1)) - 1
                For $C = 0 To Random(UBound($Array, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $Array[$B][$C])

                Next

            Next
            DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])

WEnd

While timerdiff($start1) >= 10000 AND timerdiff($start1) < 20000


            Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
            For $B = 0 To Random(UBound($BArray, 1)) - 1
                For $C = 0 To Random(UBound($BArray, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $BArray[$B][$C])
                Next
            Next
            DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])

WEnd

While timerdiff($start1) >= 20000 AND timerdiff($start1) < 30000


            Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
            For $B = 0 To Random(UBound($CArray, 1)) - 1
                For $C = 0 To Random(UBound($CArray, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $CArray[$B][$C])
                Next
            Next
            DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])

WEnd

While timerdiff($start1) >= 30000

If timerdiff($start1) > 40000 Then
    exit
endif

            Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
            For $B = 0 To Random(UBound($DArray, 1)) - 1
                For $C = 0 To Random(UBound($DArray, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $DArray[$B][$C])
                Next
            Next
            DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])

WEnd







; Modified from http://www.autoitscript.com/forum/index.php?showtopic=7315&view=findpost&p=178779
Func _PixelSetColor($XCoord, $YCoord, $Color)
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    If Not IsArray($dc) Then Return -1
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $XCoord, "long", $YCoord, "long", _
            "0x" & StringRegExpReplace(hex($Color,6), "(..)(..)(..)", "\3\2\1")) ; Change to 0xBBGGRR hex colour format.
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
EndFunc ;==>_PixelSetColor
Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

For $B = 0 To Random(UBound($DArray, 1)) - 1
                For $C = 0 To Random(UBound($DArray, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $DArray[$B][$C])
                Next
            Next

Your random statements are returning floating point numbers. Your array addresses need to be integers.

Try using something more like this

For $B = 0 To Random(1, UBound($DArray, 1), 1) - 1
                For $C = 0 To Random(1, UBound($DArray, 2), 1) - 1
                    _PixelSetColor($B + 1, $C + 1, $DArray[$B][$C])
                Next
            Next

Take another look at the Random() function in the help file and how the flag works.

Link to comment
Share on other sites

That actually breaks it, as you can see if you add those flags to the example below.

I am just starting to figure out why that is, as it only serves to confuse me a tad bit more ;)

#include <GUIConstants.au3>
#include <Array.au3>
#include <Misc.au3>


;======== load image into array ==============
SplashImageOn("", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & _
        "\Examples\GUI\merlin.gif", 90, 90, 0, 0, 1)

Dim $Array[90][90]

For $B = 0 To UBound($Array, 1) - 1
    For $C = 0 To UBound($Array, 2) - 1
        $Array[$B][$C] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next

;~ _arraydisplay ($array)
SplashOff()


SplashImageOn("", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & _
        "\Examples\GUI\msoobe.jpg", 90, 90, 0, 0, 1)

Dim $BArray[90][90]

For $B = 0 To UBound($BArray, 1) - 1
    For $C = 0 To UBound($BArray, 2) - 1
        $BArray[$B][$C] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next



;========= Draw array of pixels to desktop at mouse button down ===============
Local $aMPos, $dc

$start1 = TimerInit ()

$dif = timerdiff($start1)

While timerdiff($start1) < 7000
            Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
            For $B = 0 To Random(UBound($Array, 1)) - 1
                For $C = 0 To Random(UBound($Array, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $Array[$B][$C])

                Next

            Next
            DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])

WEnd

While timerdiff($start1) >= 7000
                If timerdiff($start1) > 15000 Then
exit
endif
            Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
            For $B = 0 To Random(UBound($BArray, 1)) - 1
                For $C = 0 To Random(UBound($BArray, 2)) - 1
                    _PixelSetColor($B + 1, $C + 1, $BArray[$B][$C])
                Next
            Next
            DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])

WEnd


; Modified from http://www.autoitscript.com/forum/index.php?showtopic=7315&view=findpost&p=178779
Func _PixelSetColor($XCoord, $YCoord, $Color)
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    If Not IsArray($dc) Then Return -1
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $XCoord, "long", $YCoord, "long", _
            "0x" & StringRegExpReplace(hex($Color,6), "(..)(..)(..)", "\3\2\1")) ; Change to 0xBBGGRR hex colour format.
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
EndFunc ;==>_PixelSetColor

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

 You should find this method of randomly accessing pixels only once each, but in a random order, is a better method for achieving what you are trying to do.

#include <GUIConstants.au3>
#include <Array.au3>
#include <Misc.au3>


;======== load image into array ==============
SplashImageOn("", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & _
        "\Examples\GUI\merlin.gif", 90, 90, 0, 0, 1)

Dim $Array[90][90]

For $B = 0 To UBound($Array, 1) - 1
    For $C = 0 To UBound($Array, 2) - 1
        $Array[$B][$C] = "0x" & Hex(PixelGetColor($B, $C), 6)
    Next
Next

;~ _arraydisplay ($array)
SplashOff()


SplashImageOn("", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & _
        "\Examples\GUI\msoobe.jpg", 90, 90, 0, 0, 1)


Dim $BArray[90][90]

;Create array of pixel coords and randomise the order
Dim $CArray[8100][3]
$k = 0
For $i = 0 To 89
    For $j = 0 To 89
        $CArray[$k][0] = Random(0,10000,1)
        $CArray[$k][1] = $i
        $CArray[$k][2] = $j
        $k+=1
    Next
Next
_ArraySort($CArray)

For $B = 0 To UBound($BArray, 1) - 1
    For $C = 0 To UBound($BArray, 2) - 1
        $BArray[$B][$C] = "0x" & Hex(PixelGetColor($B, $C), 6)
    Next
Next



;========= Draw array of pixels to desktop at mouse button down ===============
Local $aMPos, $dc

$start1 = TimerInit ()

$dif = timerdiff($start1)

While timerdiff($start1) < 7000
  Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    Local $B, $C
    For $i = 0 To 8099
        $B = $CArray[$i][1]
        $C = $CArray[$i][2]
        _PixelSetColor($B, $C, $Array[$B][$C])
        _HPSleep(100,0)
    Next
  DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
WEnd

While timerdiff($start1) >= 7000
  If timerdiff($start1) > 15000 Then exit
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    Local $B,$C
    For $i = 0 To 8099
        $B = $CArray[$i][1]
        $C = $CArray[$i][2]
        _PixelSetColor($B, $C, $BArray[$B][$C])
        _HPSleep(100,0)
  Next
  DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
WEnd


; Modified from http://www.autoitscript.com/forum/index.php?showtopic=7315&view=findpost&p=178779
Func _PixelSetColor($XCoord, $YCoord, $Color)
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    If Not IsArray($dc) Then Return -1
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $XCoord, "long", $YCoord, "long", _
            "0x" & StringRegExpReplace(hex($Color,6), "(..)(..)(..)", "\3\2\1")) ; Change to 0xBBGGRR hex colour format.
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
EndFunc ;==>_PixelSetColor

Func _HPSleep($iSleep, $fMs = 1)
    ; default is milliseconds, otherwise microseconds (1 ms = 1000 µs)
    If $fMs Then $iSleep *= 1000 ; convert to ms
    DllCall("ntdll.dll", "dword", "NtDelayExecution", "int", 0, "int64*", -10 * $iSleep)
EndFunc

 

Edit: Re-wrote text, to something that at least resembles english.   

Edited by Bowmore

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Link to comment
Share on other sites

Indeed I will, much obliged.

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

This is close to what i had envisioned, any further suggestions are very much appreciated.

I tried and succeeded with loading the pics from textfiles / declaring the entire array of pixels in the code -- both those methods end up being hella slower than just splashing them all at once, grabbing them, and playing them back as needed

edit: better example with multiple rows of images

edit2: added X and Y offsets for the draw - see example for tiling effect.

#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Local $image1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & "\Examples\GUI\merlin.gif"
Local $image2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & "\Examples\GUI\msoobe.jpg"
Local $image3 = "C:\Windows\Web\Wallpaper\Ascent.jpg"
Local $image4 = "C:\Windows\Web\Wallpaper\Autumn.jpg"
Local $image5 = "C:\Windows\Web\Wallpaper\Azul.jpg"
Local $image6 = "C:\Windows\Web\Wallpaper\Bliss.bmp"
Local $image7 = "C:\Windows\Web\Wallpaper\Crystal.jpg"
Local $image8 = "C:\Windows\Web\Wallpaper\Follow.jpg"
Local $image9 = "C:\Windows\Web\Wallpaper\Friend.jpg"
Local $image10 = "C:\Windows\Web\Wallpaper\Home.jpg"
Local $image11 = "C:\Windows\Web\Wallpaper\Peace.jpg"
Local $image12 = "C:\Windows\Web\Wallpaper\Power.jpg"


$yGui = 90
$rows = 3
$NumOfImgs = 4

$gui = GUICreate("", $NumOfImgs * 90, $ygui * $rows, 0 , 0, $WS_POPUPWINDOW)

;row 1

        GUICtrlCreatePic($image1, 0, 0, $yGui, $yGui)
        GUICtrlCreatePic($image2, 90, 0, $yGui, $yGui)
        GUICtrlCreatePic($image3, 180, 0, $yGui, $yGui)
        GUICtrlCreatePic($image4, 270, 0, $yGui, $yGui)

;row 2

        GUICtrlCreatePic($image5, 0, 90, $yGui, $yGui)
        GUICtrlCreatePic($image6, 90, 90, $yGui, $yGui)
        GUICtrlCreatePic($image7, 180, 90, $yGui, $yGui)
        GUICtrlCreatePic($image8, 270, 90, $yGui, $yGui)

;row 3
        GUICtrlCreatePic($image9, 0, 180, $yGui, $yGui)
        GUICtrlCreatePic($image10, 90, 180, $yGui, $yGui)
        GUICtrlCreatePic($image11, 180, 180, $yGui, $yGui)
        GUICtrlCreatePic($image12, 270, 180, $yGui, $yGui)

GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState(@SW_SHOW, $gui)

$merlin = _PicToArray(0, 0)
$oobe = _PicToArray(90, 0)
$Ascent = _PicToArray(180, 0)
$Autumn = _PicToArray(270, 0)
$Azul = _PicToArray(0, 90)
$Bliss = _PicToArray(90, 90)
$Crystal = _PicToArray(180, 90)
$Follow = _PicToArray(270, 90)
$Friend = _PicToArray(0, 180)
$Home = _PicToArray(90, 180)
$Peace = _PicToArray(180, 180)
$Power = _PicToArray(270, 180)

GUIDelete()

_DrawPicfromArray ($merlin, '1' , 0 , 0)
_DrawPicfromArray ($oobe, '1' , 30 , 30)
_DrawPicfromArray ($Ascent, '1' , 60 , 60)
_DrawPicfromArray ($Autumn, '1' , 0 , 90)
_DrawPicfromArray ($Azul, '1' , 30, 120)
_DrawPicfromArray ($Bliss, '1' , 60, 150)
_DrawPicfromArray ($Crystal, '1' , 0, 180)
_DrawPicfromArray ($Follow, '1' , 30, 210)
_DrawPicfromArray ($Friend, '1' , 60, 240)
_DrawPicfromArray ($Home, '1' , 0, 270)
_DrawPicfromArray ($Peace, '1' , 30, 300)
_DrawPicfromArray ($Power, '1' , 60, 330)




Func _PicToArray($x, $y)

    Dim $BArray[90][90]

    $firstD = UBound($BArray, 1) - 1
    $secondD = UBound($BArray, 2) - 1

    For $B = $x To $firstD + $x
    For $C = $y To $secondD + $y
        $BArray[$B - $x][$C - $y] = "0x" & Hex(PixelGetColor($B + 1, $C + 1), 6)
    Next
Next
splashoff ()
Return $BArray
EndFunc

Func _save($SrcArray , $file)
$save = fileopen ($file , 10)
for $K = 0 to Ubound($SrcArray, 1) - 1
For $L = 0 To UBound($SrcArray, 2) - 1
filewrite ($save, $SrcArray[$K][$L] & @CRLF)
Next
Next
FileClose ($save)
EndFunc

Func _DrawPicfromArray($Srcarray, $TimerARG, $offsetX , $offsetY)

    Dim $ZArray[8100][3]
$k = 0
For $i = 0 To 89
    For $j = 0 To 89
        $ZArray[$k][0] = Random(0,10000,1)
        $ZArray[$k][1] = $i
        $ZArray[$k][2] = $j
        $k+=1
    Next
Next
_ArraySort($ZArray)

;========= Draw array of pixels to desktop at mouse button down ===============
Local $aMPos, $dc

$start1 = TimerInit ()
$dif = timerdiff($start1)

While 1
    If timerdiff($start1) >= $TimerARG Then
        ExitLoop
        Endif
  Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    Local $D, $E
    For $i = 0 To 8099
        $D = $ZArray[$i][1]
        $E = $ZArray[$i][2]
        _PixelSetColor($D + $offsetX, $E + $offsetY, $Srcarray[$D][$E])
        _HPSleep(100,0)
    Next
  DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
WEnd
EndFunc

; Modified from http://www.autoitscript.com/forum/index.php?showtopic=7315&view=findpost&p=178779
Func _PixelSetColor($XCoord, $YCoord, $Color)
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    If Not IsArray($dc) Then Return -1
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $XCoord, "long", $YCoord, "long", _
            "0x" & StringRegExpReplace(hex($Color,6), "(..)(..)(..)", "\3\2\1")) ; Change to 0xBBGGRR hex colour format.
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "hwnd", $dc[0])
EndFunc ;==>_PixelSetColor

Func _HPSleep($iSleep, $fMs = 1)
    ; default is milliseconds, otherwise microseconds (1 ms = 1000 µs)
    If $fMs Then $iSleep *= 1000 ; convert to ms
    DllCall("ntdll.dll", "dword", "NtDelayExecution", "int", 0, "int64*", -10 * $iSleep)
EndFunc
Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

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...