Sign in to follow this  
Followers 0

Get or Read Pixel from Memory UDF - PixelGetColor .au3

56 posts in this topic

#21 ·  Posted

thank you very much.!!

Share this post


Link to post
Share on other sites



#22 ·  Posted

I have it uploaded (Thanks to NeoFoX) but the example still is missing. I'm waiting for Gary to reply to this thread, see if he still has a version of the example.

I believe it was:

#include <PixelGetColor.au3>
#include <Misc.au3>

$vDC = _PixelGetColor_CreateDC()

$vRegion = _PixelGetColor_CaptureRegion($vDC, 0,0,@DesktopWidth,@DesktopHeight)

$hDll = DllOpen("gdi32.dll")

; click left mouse button to exit
While Not _IsPressed(0x01)
    $aPos = MouseGetPos()
    $sColor = _PixelGetColor_GetPixel($vDC, $aPos[0],$aPos[1], $hDll)

    ToolTip("The color under your mouse is: " & $sColor, $aPos[0]+3, $aPos[1]+3, "_PixelGetColor_GetPixel return")
WEnd

DllClose($hDll)

_PixelGetColor_ReleaseRegion($vRegion)

_PixelGetColor_ReleaseDC($vDC)

SciTE for AutoItDirections for Submitting Standard UDFs


Don't argue with an idiot; people watching may not be able to tell the difference.

Share this post


Link to post
Share on other sites

#23 ·  Posted

I believe it was:

#include <PixelGetColor.au3>
#include <Misc.au3>

$vDC = _PixelGetColor_CreateDC()

$vRegion = _PixelGetColor_CaptureRegion($vDC, 0,0,@DesktopWidth,@DesktopHeight)

$hDll = DllOpen("gdi32.dll")

; click left mouse button to exit
While Not _IsPressed(0x01)
    $aPos = MouseGetPos()
    $sColor = _PixelGetColor_GetPixel($vDC, $aPos[0],$aPos[1], $hDll)

    ToolTip("The color under your mouse is: " & $sColor, $aPos[0]+3, $aPos[1]+3, "_PixelGetColor_GetPixel return")
WEnd

DllClose($hDll)

_PixelGetColor_ReleaseRegion($vRegion)

_PixelGetColor_ReleaseDC($vDC)
This will not work because the function "_PixelGetColor_GetPixel" accepts two parameters not 4, and Autoit throws an error saying wrong number of parameters. Anyone have a working example, or know what to change?

Share this post


Link to post
Share on other sites

#24 ·  Posted (edited)

This one works for me, just had to remove the fourth parameter.

#include <PixelGetColor.au3>
#include <Misc.au3>

$vDC = _PixelGetColor_CreateDC()

$vRegion = _PixelGetColor_CaptureRegion($vDC, 0,0,@DesktopWidth,@DesktopHeight)

$hDll = DllOpen("gdi32.dll")

; click left mouse button to exit
While Not _IsPressed(0x01)
    $aPos = MouseGetPos()
    $sColor = _PixelGetColor_GetPixel($vDC, $aPos[0],$aPos[1])

    ToolTip("The color under your mouse is: " & $sColor, $aPos[0]+3, $aPos[1]+3, "_PixelGetColor_GetPixel return")
WEnd

DllClose($hDll)

_PixelGetColor_ReleaseRegion($vRegion)

_PixelGetColor_ReleaseDC($vDC)
Edited by xekon

Share this post


Link to post
Share on other sites

#25 ·  Posted

Sorry about that, Xekon. I had an old version up there.

Fixed in last update. :)

Share this post


Link to post
Share on other sites

#26 ·  Posted

I also tried to automate a flash game, which failed horribly. I think I should not hide it's results.

This shows AutoIt in it's pure slowness.

#include <GUIConstants.au3>
#include <_PixelGetColor.au3>  ; MAGIC!
; Full topic here: http://www.autoitscript.com/forum/index.php?showtopic=63318

Global $Aimbot = 0, $vRegion

Opt("MouseClickDelay", 0)
Opt("MouseClickDownDelay", 0)

HotKeySet("{Space}", "ToggleAimbot")
    
$oGame = ObjCreate ("ShockwaveFlash.ShockwaveFlash.1")
$GameForm = GUICreate("Aimbot Proof of Concept", 820, 660, 0, 0)
$GUIActiveX = GUICtrlCreateObj ($oGame, 10, 10, 800, 580)
$exitbutton = GUICtrlCreateButton("Exit", 704, 624, 89, 25)
GUICtrlCreateLabel("Hit [Space] to toggle the aimbot", 16, 608, 300, 17)
$status = GUICtrlCreateLabel("Aimbot Status: Off", 16, 624, 500, 33)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")


With $oGame
    .bgcolor = "#000000"
    .Movie = 'http://farm.addictinggames.com/D78AQSAKQLQWI9/2025.swf'
    .ScaleMode = 2
    .Loop = True
    .wmode = "Opaque"
EndWith
GUICtrlCreateLabel("Aimbot Options:", 340, 608, 78, 17)

$hDll = DllOpen("gdi32.dll")
$vDC = _PixelGetColor_CreateDC($hDll)

GUISetState()

While 1
    If $Aimbot = 1 Then; Auto-Aim + Autoshoot
        $vRegion = _PixelGetColor_CaptureRegion($vDC, 10,10,800,500,$hDll)
        
        For $x = 0 to 790
            For $y = 0 to 490
                $sColor = _PixelGetColor_GetPixel($vDC, $x, $y, $hDll)
                If $sColor = "FF9986" Then
                    MouseClick('left', $x, $y, 1, 0)
                    Send("r")
                EndIf
            Next
        Next
        
    EndIf

    $msg = GUIGetMsg()
    Switch $msg
        Case $exitbutton, $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

_PixelGetColor_ReleaseRegion($vRegion)
_PixelGetColor_ReleaseDC($vDC,$hDll)
DllClose($hDll)
Exit

Func ToggleAimbot()
    If $Aimbot < 1 Then
        $Aimbot = $Aimbot + 1
    Else
        $Aimbot = 0
    EndIf
    Select
        Case $Aimbot = 0
            GUICtrlSetData($status, "Aimbot Status: Off")
        Case $Aimbot = 1
            GUICtrlSetData($status, "Aimbot Status: AutoFind + AutoShoot")
    EndSelect
EndFunc

Share this post


Link to post
Share on other sites

#27 ·  Posted

Hey, although this does work for a single pixel how would you use this to search for range or variations as you would with PixelSearch

Share this post


Link to post
Share on other sites

#28 ·  Posted

Hey, although this does work for a single pixel how would you use this to search for range or variations as you would with PixelSearch

Somewhat like in the example above, only you'd have to write your own algorithm for determining the difference between two colors.

I have something like it on my computer, but it isn't AutoIt. I hope you can understand it and convert it into AutoIt.

ColorDiff.R = Color1.R - Color2.R
ColorDiff.G = Color1.G - Color2.G
ColorDiff.B = Color1.B - Color2.B
if (ColorDiff.R < 0) then ColorDiff.R *= -1 end
if (ColorDiff.G < 0) then ColorDiff.G *= -1 end
if (ColorDiff.B < 0) then ColorDiff.B *= -1 end

ColorDifference = ColorDiff.R + ColorDiff.G + ColorDiff.B

if (ColorDifference < 100) then
    -- 100 is the sensitivity here
    -- do stuff
end

Share this post


Link to post
Share on other sites

#29 ·  Posted

I can understand it sertanly but since i am a total AutoIt nub i have no chance of making this into a proper algo...:\

Share this post


Link to post
Share on other sites

#30 ·  Posted

Just saw this again and thought I'd drop in tell you what a great job you did. I find myself using this more and more.


[center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw

Share this post


Link to post
Share on other sites

#31 ·  Posted

I know this is an old thread, but I just stumbled across it and thought it'd be perfect for what I'm looking for. The only problem is that it seems to be significantly slower than PixelGetColor()?!

Here's a test script:

#include <_PixelGetColor.au3>
#include <Misc.au3>

$init=TimerInit()
For $x=1 To 320
    For $y=1 To 240
        PixelGetColor($x,$y)
    Next
Next
MsgBox(0,"","100%: " & TimerDiff($init) & @crlf & "Average: " & TimerDiff($init)/($x * $y))

$hDll = DllOpen("gdi32.dll")
$vDC = _PixelGetColor_CreateDC($hDll)
$vRegion = _PixelGetColor_CaptureRegion($vDC, 0,0,320,240,$hDll)
$init=TimerInit()
For $x=1 To 320
    For $y=1 To 240
        _PixelGetColor_GetPixel($vDC, $x,$y, $hDll)
    Next
Next
MsgBox(0,"","100%: " & TimerDiff($init) & @crlf & "Average: " & TimerDiff($init)/($x * $y))

Upon running it, I get the following:

PixelGetColor():

Time: ~10563 ms

Avg: ~0.13655 ms

_PixelGetColor_CreateDC():

Time: ~47431 ms

Avg: ~0.61312 ms

Am I doing something wrong? Would love to have a faster alternative to PixelGetColor.

Share this post


Link to post
Share on other sites

#32 ·  Posted

chantling, this is not a replacement for PixelGetColor. The ideal way to use this would be for OCR, where you need to read many pixels that are concurrent with each other. After 10 seconds of reading pixels into an array, the screen has probably refreshed itself a few hundreds of times. With this method you will read all the pixels at once, and make them available to AutoIt at a later stage.

Your results are horrible though:

PixelGetColor():

Time: ~1208 ms

Avg: ~0.0157 ms

_PixelGetColor_CreateDC():

Time: ~3328 ms

Avg: ~0.0430 ms

Share this post


Link to post
Share on other sites

#33 ·  Posted

Ah, ok. I understood the benefit of taking the one snapshot and not having to worry about the screen refreshing - I was (still am) thinking about using it for simple image recognition. I just thought that it would be faster than PixelGetColor b/c you're only taking the screenshot once, then operating on it from memory, whereas my understanding was that pixelgetcolor took a snapshot every time it's called.

Share this post


Link to post
Share on other sites

#34 ·  Posted (edited)

Updated for speed. No longer relies on string operations (*shame*).

Compatibility with previous versions is "non-existent" also known as script breaking.

I still recommend using the _PixelGetColor_GetRaw function and rewriting your algorithm to use BGR.

PixelGetColor

100%: 1311.44265542129

Average: 0.0169525595608418

_PixelGetColor_GetPixel

100%: 4878.42141948209

Average: 0.0630606773946629

_PixelGetColor_GetPixelRaw

100%: 2670.78301851213

Average: 0.0345238347952256

Test script:

#include <_PixelGetColor.au3>
#include <Misc.au3>

$init=TimerInit()
For $x=1 To 320
    For $y=1 To 240
        PixelGetColor($x,$y)
    Next
Next
ConsoleWrite("[b]PixelGetColor[/b]" & @CRLF & "100%: " & TimerDiff($init) & @crlf & "Average: " & TimerDiff($init)/($x * $y) & @CRLF & @CRLF)

$hDll = DllOpen("gdi32.dll")
$vDC = _PixelGetColor_CreateDC()
$vRegion = _PixelGetColor_CaptureRegion($vDC, 0,0,320,240)
$init=TimerInit()
For $x=1 To 320
    For $y=1 To 240
        _PixelGetColor_GetPixel($vDC, $x,$y, $hDll)
    Next
Next
ConsoleWrite("[b]_PixelGetColor_GetPixel[/b]" & @CRLF & "100%: " & TimerDiff($init) & @crlf & "Average: " & TimerDiff($init)/($x * $y) & @CRLF & @CRLF)
DllClose($hDll)

$hDll = DllOpen("gdi32.dll")
$vDC = _PixelGetColor_CreateDC()
$vRegion = _PixelGetColor_CaptureRegion($vDC, 0,0,320,240)
$init=TimerInit()
For $x=1 To 320
    For $y=1 To 240
        _PixelGetColor_GetPixelRaw($vDC, $x,$y, $hDll)
    Next
Next
ConsoleWrite("[b]_PixelGetColor_GetPixelRaw[/b]" & @CRLF & "100%: " & TimerDiff($init) & @crlf & "Average: " & TimerDiff($init)/($x * $y) & @CRLF)
DllClose($hDll)
Edited by Manadar

Share this post


Link to post
Share on other sites

#35 ·  Posted

Why are you guys bothering? There is little great function: PixelSearch()

Test for 300x300 area:

PixelGetColor

100%: 1295.54316743593

Average: 0.00516157297825462

PixelSearch

100%: 3.46136755706857

Average: 1.39017151978103e-005

SOLUTION: AutoIt team, PLEASE provide more of simple built-in functions! :D


Too lazy for anything other than AutoIT.

Share this post


Link to post
Share on other sites

#36 ·  Posted (edited)

Lrn2read. Seriously, both the search function, AND the information already in the threads you've posted in should be more than enough for whatever it is that you want.

To be more specific, this gets the pixel from memory, not from the screen, meaning you can grab screenshots from minimized applications, effectively enabling you to automate as many concurrent instances as your hardware can handle. This script is pure gold, and your criticism is tripe. Think, or at least read, before you post next time.

Edited by JRowe

Share this post


Link to post
Share on other sites

#37 ·  Posted (edited)

I totally Agree! It is a great UDF to add.

Can you imagine using it for a game? Something that needs to respond to a pixel faster then 1 second delay?

I know there will be new pixel search addition in the 3.3.1.0? ( search pixel starting from left, right, bottom and top)

Pixel functions are VERY CPU intensive because there are a lot of pixels to deal with. The best solution is to have built in algorithms that run C++! they are simple yet do a lot of work x1000 faster.

Edited by dexto

Too lazy for anything other than AutoIT.

Share this post


Link to post
Share on other sites

#38 ·  Posted

Do you thing there could be a better way to capture screen to an array?

_PixelGetColor_CaptureRegion
100%: 6.34111961370737

_PixelGetColor_GetPixelRaw
100%: 110123.193945799
Average: 0.0623316217440469

#include <_PixelGetColor.au3>
#include <Misc.au3>

    Global $w=@DesktopWidth
    Global $h=@DesktopHeight

$hDll = DllOpen("gdi32.dll")
$vDC = _PixelGetColor_CreateDC()
$init = TimerInit()
$vRegion = _PixelGetColor_CaptureRegion($vDC, 0, 0, $w, $h)
ConsoleWrite("_PixelGetColor_CaptureRegion" & @CRLF & "100%: " & TimerDiff($init) & @CRLF & @CRLF)

Dim $pix[$w][$h]
$init = TimerInit()
For $x = 1 To $w
    For $y = 1 To $h
        $pix[$x-1][$y-1]=_PixelGetColor_GetPixelRaw($vDC, $x, $y, $hDll)
    Next
Next
ConsoleWrite("_PixelGetColor_GetPixelRaw" & @CRLF & "100%: " & TimerDiff($init) & @CRLF & "Average: " & TimerDiff($init) / ($x * $y) & @CRLF)
DllClose($hDll)

Too lazy for anything other than AutoIT.

Share this post


Link to post
Share on other sites

#39 ·  Posted

i did some research and:

Memory Device Contexts

To enable applications to place output in memory rather than sending it to an actual device, use a special device context for bitmap operations called a memory device context. A memory DC enables the system to treat a portion of memory as a virtual device. It is an array of bits in memory that an application can use temporarily to store the color data for bitmaps created on a normal drawing surface. Because the bitmap is compatible with the device, a memory DC is also sometimes referred to as a compatible device context.

The memory DC stores bitmap images for a particular device. An application can create a memory DC by calling the CreateCompatibleDC function.

The original bitmap in a memory DC is simply a placeholder. Its dimensions are one pixel by one pixel. Before an application can begin drawing, it must select a bitmap with the appropriate width and height into the DC by calling the SelectObject function. To create a bitmap of the appropriate dimensions, use the CreateBitmap, CreateBitmapIndirect, or CreateCompatibleBitmap function. After the bitmap is selected into the memory DC, the system replaces the single-bit array with an array large enough to store color information for the specified rectangle of pixels.

When an application passes the handle returned by CreateCompatibleDC to one of the drawing functions, the requested output does not appear on a device's drawing surface. Instead, the system stores the color information for the resultant line, curve, text, or region in the array of bits. The application can copy the image stored in memory back onto a drawing surface by calling the BitBlt function, identifying the memory DC as the source device context and a window or screen DC as the target device context.

http://msdn.microsoft.com/en-us/library/dd145049(VS.85).aspx

Is it possible to access that array directly?


Too lazy for anything other than AutoIT.

Share this post


Link to post
Share on other sites

#40 ·  Posted

I am using that array directly. The problem is that it only comes out one pixel at a time and so you have to rebuild the array and the DllCall's are quite slow. Maybe this could be rewritten as a plugin if that would be faster. Does anyone else have some experience in that?

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