Jump to content
Sign in to follow this  
Xibalba

PixelGetColor speed issues

Recommended Posts

Xibalba

This script takes a total of ~6 seconds for me, each test taking ~1 sec:

Global $wnd=WinGetHandle("[ACTIVE]")
Global $total_time
Global $result



$n1 = 60000
$start_time = TimerInit()
For $i = 1 To $n1
  PixelGetColor(1, 1)
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$result &= "1. PixelGetColor: same screen pixel, omitting handle parameter: " & $time1 & " ms" & @LF

Sleep(30)

$start_time = TimerInit()
For $x = 0 To 299
  For $y = 0 To 199
    PixelGetColor($x, $y)
  Next
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$result &= "2. PixelGetColor: screen rectangle 300x200 pixels, omitting handle parameter: " & $time1 & " ms" & @LF

Sleep(30)

$n1 = 60000
$start_time = TimerInit()
For $i = 1 To $n1
  PixelGetColor(1, 1, "")
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$result &= "3. PixelGetColor: same screen pixel, using parameter "": " & $time1 & " ms" & @LF

Sleep(30)

$start_time = TimerInit()
For $x = 0 To 299
  For $y = 0 To 199
    PixelGetColor($x, $y)
  Next
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$result &= "4. PixelGetColor: screen rectangle 300x200 pixels, using parameter "": " & $time1 & " ms" & @LF

Sleep(30)

$n1 = 60000
$start_time = TimerInit()
For $i = 1 To $n1
  PixelGetColor(1, 1, $wnd)
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$result &= "5. PixelGetColor: same screen pixel, using parameter [Active]: " & $time1 & " ms" & @LF

Sleep(30)

$start_time = TimerInit()
For $x = 0 To 299
  For $y = 0 To 199
    PixelGetColor($x, $y, $wnd)
  Next
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$result &= "6. PixelGetColor: screen rectangle 300x200 pixels, using parameter [Active]: " & $time1 & " ms" & @LF

$result &= @LF
$result &= "Total time: " & $total_time & " ms" ; exluding sleep's


MsgBox(0, "mBox", $result)
  • What results do you get? (XP users particulary of interest)
  • Is my numbers normal/expected?
  • Is there any way to speed this up (staying with default functions)?

 

I've been looking for alternatives and one seems to be _GDIPlus_BitmapLockBits with a simple example available >here.

That example makes my AutoIt crash completely though (even with handle "" specified). >Another example also crashes for me, so I'm a bit lost.

Does the GDIPlus example(s) work for you?

I'd love to stay with PixelGetColor for now, if possible.

Any help greatly appreciated.

Machine:

WinXP Pro SP3

GPU 1GB GeForce

3 GB RAM

1600x1200x32

Window Classic theme

AutoIt v3.3.10.2

Share this post


Link to post
Share on other sites
Geir1983

I know you say you want to stay with the basic functions, but you should take a look at FastFind project in the example scripts

 

From FastFrench's description:

"- For even more performance, you can capture the content of a screen memory (SnapShot, takes about the same time as or PixelSearch PixelGetColor) then do all the research you want in this snapshots (very fast functions : nearly 1000 times as fast as the native PixelGetColor)."

Share this post


Link to post
Share on other sites
Kovacic

$n1 = 60000
$start_time = TimerInit()
For $i = 1 To $n1
  PixelGetColor(1, 1, $wnd)
Next

Out of all your FOR loops, you have 180,897 executions. That along with your sleep functions, I would say 6 seconds is pretty good.


C0d3 is P0etry( ͡° ͜ʖ ͡°)

Share this post


Link to post
Share on other sites
Xibalba

I know you say you want to stay with the basic functions, but you should take a look at FastFind project in the example scripts

 

From FastFrench's description:

"- For even more performance, you can capture the content of a screen memory (SnapShot, takes about the same time as or PixelSearch PixelGetColor) then do all the research you want in this snapshots (very fast functions : nearly 1000 times as fast as the native PixelGetColor)."

 

Yes, FastFind and _GDIPlus_BitmapLockBits are the two alternatives I've found so far.

I took the liberty to refine my benchmark script and also include FastFind (Advanced Pixel Search Library)

.

I don't know why the test results from my benchmark is a dissapointment compared to the benchmark included in FastFind v2.2, but my script shows that:

  • Using the wrapper (which works), performance is decreased by ~25%.
  • Using DLLCall directly (which doesn't seem to work, se below), performance is increased by ~25%.

 

In Test #5 and #6, the DllCall() returns an empty string - "" - for every call (pixel). Not sure why. Isn't this supposed to be the way it should be used?

;PixelGetColor vs FFGetPixel v1.0.au3

#include "FastFind.au3"
FFSetDebugMode(0) ; No debugging = fastest possible

Global $array1[30000]
Global Const $n1 = 30000
Global $array2[200][150]
Global $total_time
Global $resultStr

Func ClearArray1()
  For $i = 0 To UBound($array1) - 1
    $array1[$i] = ""
  Next
EndFunc

Func ClearArray2()
  For $i = 0 To UBound($array2, 1) - 1
    For $j = 0 To UBound($array2, 2) - 1
      $array2[$i][$j] = ""
    Next
  Next
EndFunc


; 1
$start_time = TimerInit()
For $i = 1 To $n1
  $array1[$i-1] = PixelGetColor(1, 1)
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$resultStr &= "1. Native PixelGetColor: Top-left single screen pixel (" & $n1 & " calls): " & $time1 & " ms" & @LF

Sleep(30)
ClearArray1()

; 2
$start_time = TimerInit()
For $x = 0 To 199 ; or 299 / 199 for 60,000
  For $y = 0 To 149
    $array2[$x][$y] = PixelGetColor($x, $y)
  Next
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$resultStr &= "2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): " & $time1 & " ms" & @LF

Sleep(30)
ClearArray2()

; 3
$start_time = TimerInit()
FFSnapShot() ; To keep it simple, a FullScreen capture here
For $i = 1 To $n1
  $array1[$i-1] = FFGetPixel(1, 1)
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$resultStr &= "3. FFGetPixel (via Wrapper): Top-left single screen pixel (" & $n1 & " calls): " & $time1 & " ms" & @LF

Sleep(30)
ClearArray1()

; 4
$start_time = TimerInit()
For $x = 0 To 199
  For $y = 0 To 149
    $array2[$x][$y] = FFGetPixel($x, $y)
  Next
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$resultStr &= "4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): " & $time1 & " ms" & @LF

Sleep(30)
ClearArray2()

; 5
$start_time = TimerInit()
FFSnapShot() ; To keep it simple, a FullScreen capture here
For $i = 1 To $n1
  $array1[$i-1] = DllCall($FFDllHandle, "int", "FFGetPixel", "int", 1, "int", 1, "int", $FFLastSnap)
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$resultStr &= "5. FFGetPixel (direct DLL): Top-left single screen pixel (" & $n1 & " calls): " & $time1 & " ms" & @LF

Sleep(30)
ClearArray1()

; 6
$start_time = TimerInit()
FFSnapShot() ; To keep it simple, a FullScreen capture here
For $x = 0 To 199
  For $y = 0 To 149
    $array2[$x][$y] = DllCall($FFDllHandle, "int", "FFGetPixel", "int", $x, "int", $y, "int", $FFLastSnap)
  Next
Next
$time1=int(TimerDiff($start_time))
$total_time += $time1
$resultStr &= "6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): " & $time1 & " ms" & @LF



; View results
$resultStr &= @LF
$resultStr &= "Total time: " & $total_time & " ms" ; excluding sleep's

MsgBox(0, "mBox", $resultStr)

I'd love to include _GDIPlus_BitmapLockBits in this benchmark script, but as mentioned in the first post - the _GDIPlus_BitmapLockBits() function call crashes completely for me.

Share this post


Link to post
Share on other sites
Melba23

Xibalba,

 

the _GDIPlus_BitmapLockBits() function call crashes completely

There is a typographical error in a GDI function which we have only just noticed - perhaps this is the source of your crash. Open the GDIPlus.au3 file and in the BitmapFromMemory function look for the string "GlobalUnlbck" - change it to "GlobalUnlock".

Please let me know if that stopped the crash. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Xibalba

Xibalba,

 

There is a typographical error in a GDI function which we have only just noticed - perhaps this is the source of your crash. Open the GDIPlus.au3 file and in the BitmapFromMemory function look for the string "GlobalUnlbck" - change it to "GlobalUnlock".

Please let me know if that stopped the crash. :)

M23

Hello,

No such typo in my GDIPlus.au3 file.

I suppose you mean this function?

Func _GDIPlus_BitmapCreateFromMemory($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult = 0
    Local Const $memBitmap = Binary($bImage) ;load image saved in variable (memory) and convert it to binary
    Local Const $iLen = BinaryLen($memBitmap) ;get binary length of the image
    Local Const $GMEM_MOVEABLE = 0x0002
    $aResult = DllCall("kernel32.dll", "handle", "GlobalAlloc", "uint", $GMEM_MOVEABLE, "ulong_ptr", $iLen) ;allocates movable memory ($GMEM_MOVEABLE = 0x0002)
    If @error Then Return SetError(4, 0, 0)
    Local Const $hData = $aResult[0]
    $aResult = DllCall("kernel32.dll", "ptr", "GlobalLock", "handle", $hData)
    If @error Then Return SetError(5, 0, 0)
    Local $tMem = DllStructCreate("byte[" & $iLen & "]", $aResult[0]) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    DllCall("kernel32.dll", "bool", "GlobalUnlock", "handle", $hData) ;decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE
    If @error Then Return SetError(6, 0, 0)
    Local Const $hStream = _WinAPI_CreateStreamOnHGlobal($hData) ;creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then Return SetError(2, 0, 0)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromStream($hStream) ;creates a Bitmap object based on an IStream COM interface
    If @error Then Return SetError(3, 0, 0)
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "ulong_ptr", 8 * (1 + @AutoItX64), "uint", 4, "ushort", 23, "uint", 0, "ptr", 0, "ptr", 0, "str", "") ;release memory from $hStream to avoid memory leak
    If $hHBITMAP Then
        Local Const $hHBmp = __GDIPlus_BitmapCreateDIBFromBitmap($hBitmap) ;supports GDI transparent color format
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateFromMemory

"GlobalUnlbck" doesn't exist anywhere in GDIPlus.au3 file for me.

v3.3.10.2

Share this post


Link to post
Share on other sites
Melba23

Xibalba,

Must just be in the Beta then - sorry to have raised your hopes without return. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Xibalba

Also, can someone help me with a simple script to use the GDIPlus equivalent to PixelGetColor (DllStructGetData($BitmapData, "Scan0")?).

Just a x,y check of what is currently visible on my screen (and not a specific handle! - what happens if we try to use "" anyway?).

What functions do I use? And how?

_GDIPlus_BitmapCreateFromMemory?
_GDIPlus_BitmapCreateFromGraphics?
_GDIPlus_BitmapCreateFromScan0?

Most examples in the forums are, as said, crashing for me, so a minimal script to test would be awesome (to at least get closer to understand why it's crashing)

Share this post


Link to post
Share on other sites
Xibalba

My endgame is live Picture- and Video-analysis and manipulation - so speed is of most importance.

Rest assured though, it's not against any of the forum rules.

If anyone know the GDIPlus equivalent to PixelGetColor(), with a minimalistic example using what is currently shown on the screen, I'd be very grateful.

Thx

Edited by Xibalba

Share this post


Link to post
Share on other sites
Geir1983

This is my result from your test, FF is clearly working for me, did you put the dlls in your script directory?

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 542230 ms
2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 501217 ms
3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 797 ms
4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 744 ms
5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 497 ms
6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 494 ms

Total time: 1045979 ms

Laptop:

Intel Core Duo

Nvidia Quadro NVS 160M

4gb RAM

Windows 7 (32 bit)

Share this post


Link to post
Share on other sites
Xibalba

This is my result from your test, FF is clearly working for me, did you put the dlls in your script directory?

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 542230 ms

2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 501217 ms

3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 797 ms

4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 744 ms

5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 497 ms

6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 494 ms

Total time: 1045979 ms

Laptop:

Intel Core Duo

Nvidia Quadro NVS 160M

4gb RAM

Windows 7 (32 bit)

 

Thanks a lot for testing. My numbers:

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 496 ms
2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 489 ms
3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 640 ms
4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 632 ms
5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 415 ms
6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 421 ms

Total time: 3093 ms

Of course I have the DLL files =) Your 1 & 2 results seems awfully slow?

Share this post


Link to post
Share on other sites
Geir1983

My laptop is pretty old.. I decided to test it on my computer at home to see if it was faster, but no.. To me your 1 & 2 results seem super fast, maybe the function was optimized in AutoIt? Im using version 3.3.8.1

Results:

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 547799 ms
2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 542538 ms
3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 395 ms
4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 331 ms
5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 255 ms
6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 259 ms

Computer:

Intel Core i7-3770

AMD Radeon HD7800

8gb RAM

Windows 8 (64 bit)

Share this post


Link to post
Share on other sites
Xibalba

My laptop is pretty old.. I decided to test it on my computer at home to see if it was faster, but no.. To me your 1 & 2 results seem super fast, maybe the function was optimized in AutoIt? Im using version 3.3.8.1

Results:

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 547799 ms

2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 542538 ms

3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 395 ms

4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 331 ms

5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 255 ms

6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 259 ms

Computer:

Intel Core i7-3770

AMD Radeon HD7800

8gb RAM

Windows 8 (64 bit)

 

You probably need to disable DWM/Aero, which should speed things up.

Share this post


Link to post
Share on other sites
Geir1983

You are right. I disabled the UxSms service and tried again on my laptop. It speed up the native function, but seems to be inconsistent.. Might have been that before also, just notice alot higher execution time for the FF functions so i tried one more run.. First time the function #5 was fastest, second run fucntion #1 was fastest.

Run 1:

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 1935 ms
2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 2982 ms
3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 3579 ms
4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 3545 ms
5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 1392 ms
6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 1464 ms

Run 2:

1. Native PixelGetColor: Top-left single screen pixel (30000 calls): 753 ms
2. Native PixelGetColor: Top-left screen rectangle (200x150 pixels): 811 ms
3. FFGetPixel (via Wrapper): Top-left single screen pixel (30000 calls): 2651 ms
4. FFGetPixel (via Wrapper): Top-left screen rectangle (200x150 pixels): 2842 ms
5. FFGetPixel (direct DLL): Top-left single screen pixel (30000 calls): 998 ms
6. FFGetPixel (direct DLL): Top-left screen rectangle (200x150 pixels): 1263 ms

Share this post


Link to post
Share on other sites
Bert

My endgame is live Picture- and Video-analysis and manipulation - so speed is of most importance.

Rest assured though, it's not against any of the forum rules.

If anyone know the GDIPlus equivalent to PixelGetColor(), with a minimalistic example using what is currently shown on the screen, I'd be very grateful.

Thx

Sorry, but can you provide the name of the application you are using? You haven't told us anything we didn't already know already. If anything giving the name of the app may provide helpful information and may provide a much better approach than pixel searching.

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  

  • Similar Content

    • faustf
      By faustf
      hi guys how is possible set a speed of  all function _Ie ?? 
    • Pricehacker
      By Pricehacker
      Hello Autoit!
      Today i discovered that pixelgetcolor doesn't adapt to the DPI of the system, and i want to fix this somehow as my laptop uses 120 DPI.
      This is what i have came up with so far:
      AutoItSetOption ( "CaretCoordMode" , 0) AutoItSetOption ( "MouseCoordMode" , 0) AutoItSetOption ( "PixelCoordMode" , 0) AutoItSetOption ( "GUICoordMode" , 0) #include <MsgBoxConstants.au3> #include <Misc.au3> #include <WinAPIGdi.au3> ; enum _PROCESS_DPI_AWARENESS Global Const $PROCESS_DPI_UNAWARE = 0 Global Const $PROCESS_SYSTEM_DPI_AWARE = 1 Global Const $PROCESS_PER_MONITOR_DPI_AWARE = 2 ; enum _MONITOR_DPI_TYPE Global Const $MDT_EFFECTIVE_DPI = 0 Global Const $MDT_ANGULAR_DPI = 1 Global Const $MDT_RAW_DPI = 2 Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI HotKeySet('{ESC}','Terminate') Func Terminate() Exit EndFunc $iPD = 1 while 1 $aPos = WinGetPos("[ACTIVE]") ToolTip (PixelGetColor( MouseGetPos()[0]*(96/_DPI(0)), MouseGetPos()[1]*(96/_DPI(1))) & ', ' & MouseGetPos()[0] & ', ' & MouseGetPos()[1] ) if $iPD = 1 and Not _IsPressed(22) Then $iPD = 0 Sleep(100) EndIf if $iPD = 0 And _IsPressed(22) Then ;Page down is pressed ClipPut( 'PixelGetColor($aPos[2]' & '*' & MouseGetPos(0)/$aPos[2] & ',' & '$aPos[3]' & '*' & MouseGetPos(1)/$aPos[3] & ')' & '=' & PixelGetColor( MouseGetPos()[0], MouseGetPos()[1])) $iPD = 1 EndIf WEnd ;Functions Func _DPI($iCordinate) ;0 for x and 1 for y _WinAPI_SetProcessDpiAwareness($PROCESS_SYSTEM_DPI_AWARE) $aMonitors = _WinAPI_EnumDisplayMonitors() $aDPI = _WinAPI_GetDpiForMonitor($aMonitors[1][0], $MDT_DEFAULT) Return $aDPI[$iCordinate] EndFunc Func _WinAPI_SetProcessDpiAwareness($DPIAware) DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) If @error Then Return SetError(1, 0, 0) EndFunc Func _WinAPI_GetDpiForMonitor($hMonitor, $dpiType) Local $X, $Y $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $hMonitor, "int", $dpiType, "uint*", $X, "uint*", $Y) If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0) Local $aDPI[2] = [$aRet[3],$aRet[4]] Return $aDPI EndFunc  
      I'm pretty sure it has to do with me using the DPI in the wrong way as i dont really understand it (even after searching around on the internet for like an hour)
      It would really help if anyone could help me on the right track
    • HardXOR
      By HardXOR
      Hello AutoIt community
      I run into speed problem in my script wich i cant solve myself, problem is with decoding texture loop - for better explanation, you need extract from file pallete (16x 16 RGB color) and picture data (224 * 128 byte), then use correct color for your picture data.... nothing extra hard and also texture is quite small 224*256
      it is for my car model viewer/later maybe editor GranTurismo 2 from Playstation 1, so its old dataformat and i cant understand why AutoIt take so long to decode texture when good old Playstation almost 2,5 decades old can do that nearly immediately (when you list through cars in shop or garage)
      My first atempt was create all trought dllstructure, because its easier approach, but it was soooo slow (40-50s for create textures) then i upgrade my routine via arrays, first 3D arrays later only 1D, next i put decoding colors outside loop but it is still not enough, my last version took cca 15s wich is still unacceptable for car model viewer when you click on one carmodel from listview (1100 cars for whole game) and you must wait 15-16s for model to load....  oh and i forgot mention some cars have more then 1 color (much more... 8-9-10 etc) soloading take 8-9-10 times more time
      in attachment i post texture file from GranTurismo 2 for one car (contain only 1 color) and also my dll struct version and array version code
      dll struct version - ± 40 sec (33 without saving)
      #include <FileConstants.au3> Global $IMDT[256][256][4] LoadTexture("ufs9r.cdp") Func LoadTexture($file) $fileHandle = FileOpen($file, $FO_BINARY) $header = FileRead($fileHandle, 0x20) ConsoleWrite("header> " & $header & @CRLF) $PAL = FileRead($fileHandle, 0x200) ConsoleWrite("PAL> " & $PAL & @CRLF) FileSetPos($fileHandle, 0x43A0, $FILE_BEGIN) $IMD = FileRead($fileHandle, 0x7000) ConsoleWrite("IMD> " & $IMD & @CRLF) $st = DllStructCreate("BYTE[512]") DllStructSetData($st, 1, $PAL) $struct_PAL = DllStructCreate("WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16]", DllStructGetPtr($st)) $struct_IMD = DllStructCreate("BYTE[" & 0x7000 & "]") DllStructSetData($struct_IMD, 1, $IMD) $start = TimerInit() For $i = 0 To 15 For $j = 0 To 223 $cn = 0 For $k = 0 To 127 $bt = DllStructGetData($struct_IMD, 1, $j * 128 + $k + 1) $blue = BitShift(DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1), 7) $IMDT[$j][$cn][0] = $blue $green = BitShift(DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1), 2) $IMDT[$j][$cn][1] = $green $red = BitShift(DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1), - 3) $IMDT[$j][$cn][2] = $red If DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1) = 0 Then $IMDT[$j][$cn][3] = 0x00 Else $IMDT[$j][$cn][3] = 0xFF EndIf $cn += 1 $blue = BitShift(DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1), 7) $IMDT[$j][$cn][0] = $blue $green = BitShift(DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1), 2) $IMDT[$j][$cn][1] = $green $red = BitAND(BitShift(DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1), - 3), 0xFF) $IMDT[$j][$cn][2] = $red If DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1) = 0 Then $IMDT[$j][$cn][3] = 0x00 Else $IMDT[$j][$cn][3] = 0xFF EndIf $cn += 1 Next Next saveTGA($i) Next ConsoleWrite("t " & TimerDiff($start) & @CRLF) ; +- 40 seconds FileClose($fileHandle) EndFunc Func saveTGA($name) Local $tga[18] = [0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x20, 0x20] Local $data for $i = 0 To 17 $data &= Hex($tga[$i], 2) Next For $i = 0 To 255 For $j = 0 To 255 For $k = 0 To 3 $data &= hex($IMDT[$i][$j][$k], 2) Next Next Next $binary = FileOpen("test\" & $name & ".tga", BitOR($FO_BINARY, $FO_OVERWRITE, $FO_CREATEPATH)) FileWrite($binary, "0x" & $data) FileClose($binary) EndFunc  
      array version - ± 15 sec (under 10s without saving)
      #include <FileConstants.au3> LoadTexture2("ufs9r.cdp") Func LoadTexture2($file) $fileHandle = FileOpen($file, $FO_BINARY) $a = TimerInit() Global $header[0x20] For $i = 0 To UBound($header) - 1 $header[$i] = Int(String(FileRead($fileHandle, 1))) ; read 0x20 bytes Next ConsoleWrite("header " & TimerDiff($a) & @CRLF) $a = TimerInit() Global $PAL[0x100] For $i = 0 To UBound($PAL) - 1 $PAL[$i] = Number(FileRead($fileHandle, 2)) ; read 0x200 (16*16) words Next Global $PALcolor[16 * 16 * 4] For $i = 0 To UBound($PAL) - 1 $PALcolor[$i * 4 + 0] = BitShift($PAL[$i], 7) $PALcolor[$i * 4 + 1] = BitShift($PAL[$i], 2) $PALcolor[$i * 4 + 2] = BitShift($PAL[$i], -3) If $PAL[$i] = 0 Then $PALcolor[$i * 4 + 3] = 0x00 Else $PALcolor[$i * 4 + 3] = 0xFF EndIf Next ConsoleWrite("PAL " & TimerDiff($a) & @CRLF) $a = TimerInit() FileSetPos($fileHandle, 0x43A0, $FILE_BEGIN) Global $IMD[0x7000] For $i = 0 To UBound($IMD) - 1 $IMD[$i] = Int(String(FileRead($fileHandle, 1))) ; read 0x7000 bytes Next ConsoleWrite("IMD " & TimerDiff($a) & @CRLF) Global $IMDT[256*256*4] $a = TimerInit() For $i = 0 To 15 For $j = 0 To 223 $cn = 0 For $k = 0 To 127 $byte = $IMD[$j * 128 + $k] ; byte for decode $index = $j * 1024 + $cn * 4 $index2 = $i * 0x40 + BitAND($byte, 0x0F) * 4 $IMDT[$index + 0] = $PALcolor[$index2 + 0] ; blue $IMDT[$index + 1] = $PALcolor[$index2 + 1] ; green $IMDT[$index + 2] = $PALcolor[$index2 + 2] ; red $IMDT[$index + 3] = $PALcolor[$index2 + 3] ; alpha $cn += 1 $index = $j * 1024 + $cn * 4 $index2 = $i * 0x40 + BitShift($byte, 4) * 4 $IMDT[$index + 0] = $PALcolor[$index2 + 0] ; blue $IMDT[$index + 1] = $PALcolor[$index2 + 1] ; green $IMDT[$index + 2] = $PALcolor[$index2 + 2] ; red $IMDT[$index + 3] = $PALcolor[$index2 + 3] ; alpha $cn += 1 Next Next ;~ $b = TimerInit() saveTGA2($i) ;~ ConsoleWrite("save TGA " & TimerDiff($b) & @CRLF) Next ConsoleWrite("full time " & TimerDiff($a) & @CRLF) ; 16 seconds FileClose($fileHandle) EndFunc Func saveTGA2($name) Local $tga[18] = [0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x20, 0x20] Local $data For $i = 0 To 17 $data &= Hex($tga[$i], 2) Next For $i = 0 To UBound($IMDT) - 1 $data &= Hex($IMDT[$i], 2) Next $binary = FileOpen("test\" & $name & ".tga", BitOR($FO_BINARY, $FO_OVERWRITE, $FO_CREATEPATH)) FileWrite($binary, "0x" & $data) FileClose($binary) EndFunc if anyone can optimize my code I would be very grateful, or pointing me to better solution, thx
      ufs9r.cdp
    • RHolmes
      By RHolmes
      I have a program that has a control that changes color a few seconds into running. So ideally, I would poll this to tell when an event has occurred. 
      I can't seem to retrieve the correct color value for a control. It always seems to return white indicating that its selecting somewhere else in the window.
      In the PixelGetColor call I'm adding half the width to the x value and subtracting half the height to the y value  in order to get the center of the control. (assuming the coords returned by ControlGetPos are top left - which i can't be sure of) But I've also tried without modifying the x/y and with changing the PixelCoordMode option to 2. Maybe I'm making a silly mistake and can't see it? Any help would be appreciated.
      Code is below:
      Opt("PixelCoordMode", 0)
      FileChangeDir( "C:\Where\My\File\Is" );
      Run( "MyProgram.exe" )
      Local $hClient = WinWaitActive( $CLIENT_TITLE, "", 10 )
      Local $systemIndicatorClassNN= "[CLASS:Qt5QWindowIcon; INSTANCE:99]"
      Local $hSystemIndicator = ControlGetHandle ( $hClient, "", $systemIndicatorClassNN)
      Local $xywh = ControlGetPos ( $hClient, "", $hSystemIndicator )
      For $i = 10 To 1 Step -1
            $color = PixelGetColor ( $xywh[0] + ($xywh[2]/2), $xywh[1] - ($xywh[3]/2), $hClient )
            LogToFile( $color )
            Sleep( 2000 )
      Next
    • Ian_Mac
      By Ian_Mac
      HotKeySet("^{SPACE}", "get_color") $colorCodeHere = ;<---------------- func get_color() Global $point = MouseGetPos() Global $color = PixelGetColor($point[0], $point[1]) MsgBox(0, "debug", "result: " & $color) EndFunc While 1 Sleep(100) WEnd Hello guys my problem is, how can i store the value that i get in that PixelGetColor($point[0], $point[0])
      i know that when i msgbox the color i will show the = of $color
      but i wanted it to be the value like  $colorCodeHere = 13456254. but  not hardcoding the value.
       
      or how could i say 
      if $color is = to $color then do this and if  $color is not  equal to $color then do that.
×