Jump to content

Recommended Posts

Posted

Currently writing a bot to peridically check 100 pixels

Turns out its kinda slow .

Friend wrote something similiar in c# and get can get 280 pixels in 0.1 sec

I get my 100 done in about 1 sec...

Dont get me wrong , it works its just 10x slower.

Pixelsearch only returns the first pixel encountered so its not what i need.

Pixelchecksum is not 100% secure so i passed on that...

Thanks

Posted

Currently writing a bot to peridically check 100 pixels

Turns out its kinda slow .

Friend wrote something similiar in c# and get can get 280 pixels in 0.1 sec

I get my 100 done in about 1 sec...

Dont get me wrong , it works its just 10x slower.

Pixelsearch only returns the first pixel encountered so its not what i need.

Pixelchecksum is not 100% secure so i passed on that...

Thanks

You can change the pixelsearch step, more step == faster searching.

Posted

You can change the pixelsearch step, more step == faster searching.

Thanks but like i said its not what i need

pixel search returns one , the first pixel , with the color tested.

I kinda need to check all 100 pixels for 5 diferent colours and take action on that.

If pixel search returned an array of locations in a rectangle where that colour could be found it might help but it doesnt

Posted (edited)

Thanks but like i said its not what i need

pixel search returns one , the first pixel , with the color tested.

I kinda need to check all 100 pixels for 5 diferent colours and take action on that.

If pixel search returned an array of locations in a rectangle where that colour could be found it might help but it doesnt

Well, you can run 5 pixelsearches, but as you said thats not optimal.

I have a code in Pascal that searches for any 256 colours in a rectangle and returns the needed coordinates in an array. Unfortunately it can't be transfered to Autoit.

I guess the only thing you could do is make your own, maybe a more experienced Autoit user will prove me wrong though.

#Edit: I just remmebered this script I made.

$File = FileOpen("Test.txt", 1);Or any other name.txt
For $i = 0 to 100 step 1;Search from X=0 to X=10
    For $j = 0 to 150 step 1;Search from Y=0 to Y=150
$I_Found_This_Pixel = PixelGetColor( $i, $j )
FileWrite ( $file, "X is: " & $i & ", Y is: " & $j & $I_Found_This_Pixel & @CRLF )
Next
Next

It will search for any colours in a certain range. Then it will write them to a .txt file for your observing.

You can modify it to write to .ini files, this will make accesing results easier.

Edited by Qousio
Posted

Well, you can run 5 pixelsearches, but as you said thats not optimal.

I have a code in Pascal that searches for any 256 colours in a rectangle and returns the needed coordinates in an array. Unfortunately it can't be transfered to Autoit.

I guess the only thing you could do is make your own, maybe a more experienced Autoit user will prove me wrong though.

#Edit: I just remmebered this script I made.

$File = FileOpen("Test.txt", 1);Or any other name.txt
For $i = 0 to 100 step 1;Search from X=0 to X=10
    For $j = 0 to 150 step 1;Search from Y=0 to Y=150
$I_Found_This_Pixel = PixelGetColor( $i, $j )
FileWrite ( $file, "X is: " & $i & ", Y is: " & $j & $I_Found_This_Pixel & @CRLF )
Next
Next

It will search for any colours in a certain range. Then it will write them to a .txt file for your observing.

You can modify it to write to .ini files, this will make accesing results easier.

Heres sample of code

for $n = 1 to 280 step +1

$here = PixelGetColor(63+$n , 848)

If $here == 0 then

$straring = $straring & "A"

ElseIf $here == 4671303 then

$straring = $straring & "B"

ElseIf $here == 15458991 Then

$straring = $straring & "C"

ElseIf $here == 2171169 then

$straring = $straring & "D"

Else

$straring = $straring & "E"

EndIf

Next

The string gets added to a dictionary and actions are taken based on the look up of that string in that dictionary in run time.

$oDictionary.ADD ($straring, $key)

There are 2 dictionaries and 20k variants on strings.

Code works

Problem is it takes 2 secs to run those 10 lines of code.

And those lines are run ... "alot"

Is there any way to import or include c# code to au3 ? Can i run c# getpixel in an au3 script ?

For those just checking this topic now , aparently c# getpixel is 10x faster.

Thanks again.

Posted

Heres sample of code

for $n = 1 to 280 step +1

$here = PixelGetColor(63+$n , 848)

If $here == 0 then

$straring = $straring & "A"

ElseIf $here == 4671303 then

$straring = $straring & "B"

ElseIf $here == 15458991 Then

$straring = $straring & "C"

ElseIf $here == 2171169 then

$straring = $straring & "D"

Else

$straring = $straring & "E"

EndIf

Next

The string gets added to a dictionary and actions are taken based on the look up of that string in that dictionary in run time.

$oDictionary.ADD ($straring, $key)

There are 2 dictionaries and 20k variants on strings.

Code works

Problem is it takes 2 secs to run those 10 lines of code.

And those lines are run ... "alot"

Is there any way to import or include c# code to au3 ? Can i run c# getpixel in an au3 script ?

For those just checking this topic now , aparently c# getpixel is 10x faster.

Thanks again.

The DirectX's pixel warp is even faster :)

Anyhow, we should let the professional Autoiters read this topic. I'm also interested in this.

Posted (edited)

Is there any way to import or include c# code to au3 ? Can i run c# getpixel in an au3 script ?

For those just checking this topic now , aparently c# getpixel is 10x faster.

Thanks again.

Of course YES.

Look at DllCall() and/or PluginOpen().

You can make your speed optimized PixelGet function in C++ or assembler or whatever else and compile it as DLL.

Then call this from AutoIt by DllCall().

Edited by Zedna
Posted

$straring=""
$timer=TimerInit()
for $n = 1 to 280 step +1
$here = PixelGetColor(63+$n , 848)
If $here == 0 then 
$straring &= "A" 
ElseIf $here == 4671303 then 
$straring &= "B"
ElseIf $here == 15458991 Then 
$straring &= "C"
ElseIf $here == 2171169 then 
$straring &= "D"
Else 
$straring &=  "E"
EndIf
Next
$td=TimerDiff($timer)
ConsoleWrite($td)

this took 4.55464 milliseconds

Posted (edited)

This way of getting pixel colours appears to be faster than your friend's getting 280 pixels in 0.1 sec.

On my XP on a 10x28 image (280 pixels),the results are 0.0111secs getting the pixels, and a further 0.0026secs getting info out of the pixel data.

Also appears to be faster than the tests conducted at

http://www.autoitscript.com/forum/index.ph...st&p=658071

Comparative results are

_ImageGetPixels (All Pixels)320x240

100%: 644.033808766198 milliseconds

Average: 0.00838655529776364 milliseconds per pixel

All results are written to console.

;
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
; http://www.autoitscript.com/forum/index.php?s=&showtopic=91755&view=findpost&p=663576
Opt('MustDeclareVars', 1)

Global $width, $height, $hGUI1, $hImage, $hGraphic1
Global $iX, $iY, $sAllPixels, $GuiX = 320, $GuiY = 240, $init, $sStr
; Search colours are white, black, yellow, blue, and red in order, and in hex BBGGRRAA format.
Global $aSearchCols[5][2] = [["FFFFFFFF", 0],["000000FF", 0],["00FFFFFF", 0], _
        ["FF0000FF", 0],["0000FFFF", 0]]

_Main()

Func _Main()
; Capture top left corner of the screen
    _ScreenCapture_Capture(@MyDocumentsDir & "\GDIPlus_Image.png", 0, 0, $GuiX, $GuiY)

; Create a GUI for the original image
    $hGUI1 = GUICreate("Original", 400, 300, 0, 0)
    GUISetState()
    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
; Initialize GDI+ library and load image
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile(@MyDocumentsDir & "\GDIPlus_Image.png")
    $iX = _GDIPlus_ImageGetWidth($hImage)
    $iY = _GDIPlus_ImageGetHeight($hImage)

; Draw original image
    $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND($hGUI1)
    _GDIPlus_GraphicsDrawImage($hGraphic1, $hImage, 0, 0)

    $init = TimerInit()

; All pixels of image are in variable, $sAllPixels, inthe format:-
; BBGGRRAA BBGGRRAA BBGGRRAA ...
    $sAllPixels = _ImageGetPixels($hImage)
    ConsoleWrite("_ImageGetPixels (All Pixels)" & $GuiX & "x" & $GuiY & @CRLF & "100%: " & _
            TimerDiff($init) & @CRLF & "Average: " & TimerDiff($init) / ($GuiX * $GuiY) & @CRLF & @CRLF)

    $init = TimerInit()

; Find specific colours and the number of times each colour is occurring in image
    Local $sStr = ""
    For $x = 0 To UBound($aSearchCols) - 1
        StringReplace($sAllPixels, $aSearchCols[$x][0], $aSearchCols[$x][0])
        $aSearchCols[$x][1] = @extended
        $sStr &= $aSearchCols[$x][0] & " appears " & $aSearchCols[$x][1] & " times " & @CRLF
    Next

; Finds the RGB colour at X, Y position. This example $x,$y position are desktop coordinates.
    Local $x = 54, $y = 60, $col, $ColRGB
    $col = StringMid($sAllPixels, ($y * $GuiX + $x) * 9 + 1, 8);
    $ColRGB = "0x" & StringRegExpReplace($col, "(.{2})(.{2})(.{2})(.{2})", "\3\2\1")
;ConsoleWrite($x & ", " & $y & " $col = " & $ColRGB &  @CRLF)

    ConsoleWrite("Doing things with the pixel data time " & $GuiX & "x" & $GuiY & @CRLF & _
            "Play time: " & TimerDiff($init) & @CRLF & _
            "coordinates (x, y) " & $x & ", " & $y & " $col = " & $ColRGB & @CRLF & $sStr)

; Loop until user exits
    Do

    Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Release resources
    _GDIPlus_GraphicsDispose($hGraphic1)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc  ;==>_Main

Func _ImageGetPixels($hImage)
    Local $Reslt, $stride, $format, $Scan0, $iIW, $iIH, $hBitmap1
    Local $v_BufferA, $AllPixels, $sREResult1, $sResult

    $iIW = _GDIPlus_ImageGetWidth($hImage)
    $iIH = _GDIPlus_ImageGetHeight($hImage)

    $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iIW, $iIH, $GDIP_PXF32ARGB)

; Locks a portion of a bitmap for reading or writing
    $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $iIW, $iIH, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)

;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData($Reslt, "Scan0")

    $v_BufferA = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0); Create DLL structure for all pixels
    $AllPixels = DllStructGetData($v_BufferA, 1)
;ConsoleWrite("$AllPixels, raw data, first 9 colours = " & StringRegExpReplace($AllPixels, "(.{98})(.*)", "\1") & @CRLF)

; Searches on this string - $sREResult1 whch has the prefix "0x"  removed, and a space put between pixels 8 characters long.
    $sREResult1 = StringRegExpReplace(StringTrimLeft($AllPixels, 2), "(.{8})", "\1 ")
;ConsoleWrite("$AllPixels, raw data, first 9 colours = " & StringRegExpReplace($sREResult1, "(.{98})(.*)", "\1") & @CRLF)

    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt); releases the locked region
    Return $sREResult1
EndFunc  ;==>_ImageGetPixels

Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    If $hWnd = $hGUI1 Then _GDIPlus_GraphicsDrawImageRect($hGraphic1, $hImage, 0, 0, $width, $height)
    Return $GUI_RUNDEFMSG
EndFunc  ;==>MY_PAINT
;
Edited by Malkey
  • Moderators
Posted

I looked into public AutoIt 3.1.0 sources.

Indeed, PixelGetColor() is using GetPixel() while PixelSearch() is using GetDIBits(). It wouldn't be required to get all the bits just to get a specific coordinate's pixel color.

If it still is horribly slow in Vista with Aero enabled, then ya'll are probably right.

@Authenticity.. Not sure if PixelSearch() uses GetDIBits() or GetDIBitSection(), but the confidence you had in that statement, you've probably read it somewhere (Or you're an incognito developer).

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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