Pixelsearch problem?? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Nwb
Posts: 444
Joined: 29 Nov 2016, 08:56

Pixelsearch problem??

23 Mar 2018, 04:09

This is strange.. This has never happened to me before with pixelsearch but for some reason it is now, can somebody explain to me what's wrong?

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn  ; Enable warnings to assist with detecting common errors.
;SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

s::
PixelSearch, X, Y, 0, 0, A_ScreenWidth, A_ScreenHeight, FDAA0C
If ErrorLevel = 0
	Msgbox Found
else If ErrorLevel = 1
	Msgbox Not Found
else If ErrorLevel = 2
	Msgbox Error
else
	Msgbox Problem
return




esc:: ExitApp
When #Warn is enabled, it says FDAA0C has not been assigned a value?
And the pixel is found regardless of whether the pixel is on the screen or not.. Coordinates of found pixel is out of the screen!

Okay I guess the color code was wrong. But does pixelsearch have a priority? Does it like search from left corner to right corner so pixels found on the left corner are found rather than the pixels on the right corner?
I am your average ahk newbie. Just.. a tat more cute. ;)
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Pixelsearch problem??

23 Mar 2018, 04:28

You should more carefully examine the content of AHK's help. Here about the format of hexadecimal values.
The decimal or hexadecimal color ID to search for, in Blue-Green-Red (BGR) format, which can be an expression. Color IDs can be determined using Window Spy (accessible from the tray menu) or via PixelGetColor.
For example: 0x9d6346
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Pixelsearch problem??

23 Mar 2018, 04:32

i mean, just read the entire doc page on pixelsearch

FDAA0C isnt a color, but an uninitialized variable
default mode pixel search expects BGR color. also id suggest prefixing them with 0x
default mode scans top to bottom, column by column from left to right, in that order

also pixelsearching your entire screen real estate, youre gonna have a bad time
User avatar
Nwb
Posts: 444
Joined: 29 Nov 2016, 08:56

Re: Pixelsearch problem??

23 Mar 2018, 04:44

swagfag wrote:i mean, just read the entire doc page on pixelsearch

FDAA0C isnt a color, but an uninitialized variable
default mode pixel search expects BGR color. also id suggest prefixing them with 0x
default mode scans top to bottom, column by column from left to right, in that order

also pixelsearching your entire screen real estate, youre gonna have a bad time
Makes sense thanks. The pixel appears on the screen in random so I have no choice unfortunately.
BoBo wrote:You should more carefully examine the content of AHK's help. Here about the format of hexadecimal values.
The decimal or hexadecimal color ID to search for, in Blue-Green-Red (BGR) format, which can be an expression. Color IDs can be determined using Window Spy (accessible from the tray menu) or via PixelGetColor.
For example: 0x9d6346
Thank you too I forgot the 0x.
I am your average ahk newbie. Just.. a tat more cute. ;)
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Pixelsearch problem??  Topic is solved

23 Mar 2018, 09:45

If you need to search a whole screen's worth of pixels and not have it take a super long time, use the GDI+ image search library instead of PixelSearch. Both .ahk files you need to #Include are attached to this post. Here's an example pixelsearch; it will tell you the color of the pixel you click on if you hold Ctrl + Alt while left clicking on the active window. Please note that GDI+ does use a very different format for pixel colors so you'll probably want to use this to identify the correct colors before writing your code.

Code: Select all

$^!LButton::
	if !pToken := Gdip_Startup()	; Start GDI+ for advanced image handling
	{
		MsgBox, 48, % "GDI+ error!", % "GDI+ failed to start. Please ensure you have gdiplus on your system!"
		return
	}
	
	pHwnd := WinExist("A")
	pHaystack := Gdip_BitmapFromHWND(pHwnd)	; Create the haystack from the active window
	
	MouseGetPos, aX, aY
	
	PixelColor := Gdip_GetPixel(pHaystack, aX, aY)	; This function works just like PixelSearch but requires a GDI+ bitmap to search
	
	Gdip_DisposeImage(pHaystack)		; Destroy the created bitmaps to free up memory
	Gdip_Shutdown(pToken)
	MsgBox % PixelColor
	return
GDI+ also has a "search by image" function if that is helpful to you. And it is massively, massively faster than PixelSearch or ImageSearch. I have a function that does a few hundred pixel searches in one go, and it was taking 15+ seconds to run; it takes less than one with GDI+.
Attachments
Gdip_ImageSearch.ahk
(33.25 KiB) Downloaded 201 times
Gdip_All.ahk
(95.45 KiB) Downloaded 192 times
User avatar
Nwb
Posts: 444
Joined: 29 Nov 2016, 08:56

Re: Pixelsearch problem??

23 Mar 2018, 10:15

MaxAstro wrote:If you need to search a whole screen's worth of pixels and not have it take a super long time, use the GDI+ image search library instead of PixelSearch. Both .ahk files you need to #Include are attached to this post. Here's an example pixelsearch; it will tell you the color of the pixel you click on if you hold Ctrl + Alt while left clicking on the active window. Please note that GDI+ does use a very different format for pixel colors so you'll probably want to use this to identify the correct colors before writing your code.

Code: Select all

$^!LButton::
	if !pToken := Gdip_Startup()	; Start GDI+ for advanced image handling
	{
		MsgBox, 48, % "GDI+ error!", % "GDI+ failed to start. Please ensure you have gdiplus on your system!"
		return
	}
	
	pHwnd := WinExist("A")
	pHaystack := Gdip_BitmapFromHWND(pHwnd)	; Create the haystack from the active window
	
	MouseGetPos, aX, aY
	
	PixelColor := Gdip_GetPixel(pHaystack, aX, aY)	; This function works just like PixelSearch but requires a GDI+ bitmap to search
	
	Gdip_DisposeImage(pHaystack)		; Destroy the created bitmaps to free up memory
	Gdip_Shutdown(pToken)
	MsgBox % PixelColor
	return
GDI+ also has a "search by image" function if that is helpful to you. And it is massively, massively faster than PixelSearch or ImageSearch. I have a function that does a few hundred pixel searches in one go, and it was taking 15+ seconds to run; it takes less than one with GDI+.
Thanks! GDI sounds interesting very helpful.
I am your average ahk newbie. Just.. a tat more cute. ;)
User avatar
noname
Posts: 515
Joined: 19 Nov 2013, 09:15

Re: Pixelsearch problem??

23 Mar 2018, 11:38

MaxAstro FYI there is a gdip pixelsearch made by Tic , here is a comparison i made between gdip imagesearch and gdip pixelsearch both searching for 1 pixel.

Greetings

Code: Select all



; downloading gdip library 
; https://www.dropbox.com/s/0e9gdfetbfa8v0o/Gdip_All.ahk
; see Tic's post https://autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/


#include *i gdip_all.ahk
#include *i gdip_imagesearch.ahk

SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1


If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}


;---------------- create demo gui ---------------- 
hbitmap:=Create_bgrd_png()


Gui, add,text,+0xE w200 h200 hwndimage_hwnd       ; +0xE is SS_BITMAP
Gui, show,,demo

SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBitmap,, ahk_id %image_hwnd%
win_title:="demo"
;---------------- end create demo gui ---------------- 




sleep 3000

Bm :=Gdip_BitmapFromHWND(WinExist(win_title))
Gdip_GetImageDimensions(Bm, w,h)


;--------------create one pixel bitmap------------
pBitmap:=Gdip_CreateBitmap(1,1)
pGraphics:= Gdip_GraphicsFromImage(pBitmap)
Gdip_GraphicsClear(pGraphics, 0xff28f028)
;-------------------------------------------------
sleep 3000

t:=a_tickcount
Gdip_PixelSearch(Bm,0xff28f028,px,py)
tpixel:= a_tickcount-t

t:=a_tickcount
Gdip_ImageSearch(Bm , pBitmap,list_image,0,0,w,h,0,,,0)
timagesearch := a_tickcount-t

msgbox % "pixelsearch= " tpixel  "ms`n" px " | " py "`n"  "imagesearch= " timagesearch "ms`n" list_image
exitapp

return
Gdip_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y)
{
	static _PixelSearch
	if !_PixelSearch
	{
		MCode_PixelSearch := "8B44241099535583E2035603C233F6C1F80239742418577E388B7C24148B6C24248B5424188D1C85000000008D64240033C085"
		. "D27E108BCF3929743183C00183C1043BC27CF283C60103FB3B74241C7CDF8B4424288B4C242C5F5EC700FFFFFFFF5DC701FFFFFFFF83C8FF5BC38B4C2"
		. "4288B54242C5F890189325E5D33C05BC3"

		VarSetCapacity(_PixelSearch, StrLen(MCode_PixelSearch)//2)
		Loop % StrLen(MCode_PixelSearch)//2      ;%
			NumPut("0x" SubStr(MCode_PixelSearch, (2*A_Index)-1, 2), _PixelSearch, A_Index-1, "char")
	}
	Gdip_GetImageDimensions(pBitmap, Width, Height)
	if !(Width && Height)
		return -1

	if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
		return -2

	x := y := 0
	E := DllCall(&_PixelSearch, "uint", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int*", x, "int*", y)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -3 : E
}





!v::listvars

esc::
Gdip_Shutdown(pToken)
ExitApp
;---------------- ---------------- ---------------- ---------------- ---------------- 
; only for creating demo gui image

; ##################################################################################
; # This #Include file was generated by Image2Include.ahk, you must not change it! #
; ##################################################################################
Create_bgrd_png(NewHandle := False) {
Static hBitmap := 0
If (NewHandle)
   hBitmap := 0
If (hBitmap)
   Return hBitmap
VarSetCapacity(B64, 396 << !!A_IsUnicode)
B64 := "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AkZBiEH7Oc3tAAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAAAn0lEQVR42u3QQQ0AIAwEMELOxBzMvzIk8J4FaCV0LQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+kEoqHh62FQAAAAAAAAAAAAAAwNSnJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMB0AUZwAYVNlk1sAAAAAElFTkSuQmCC"
If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
   Return False
VarSetCapacity(Dec, DecLen, 0)
If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
   Return False
; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "UPtr")
VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)
DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
Return hBitmap
}


MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Pixelsearch problem??

23 Mar 2018, 15:26

noname wrote:MaxAstro FYI there is a gdip pixelsearch made by Tic , here is a comparison i made between gdip imagesearch and gdip pixelsearch both searching for 1 pixel.

Greetings
Forgive my confusion - isn't that the library I included in my post? Is there a different GDI+ pixelsearch than the one I am using?
User avatar
noname
Posts: 515
Joined: 19 Nov 2013, 09:15

Re: Pixelsearch problem??

23 Mar 2018, 16:04

Now i am confused :?

Do you mean this code:

Code: Select all

PixelColor := Gdip_GetPixel(pHaystack, aX, aY)	; This function works just like PixelSearch but requires a GDI+ bitmap to search
I scanned your libraries that are attached but did not find a "pixelsearch" in it ( are my editor is fooling me :) )

The function i posted from Tic is a "real" pixelsearch using "Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1)" for fast bitmap memory access.
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Pixelsearch problem??

26 Mar 2018, 08:25

Oh, I didn't notice the difference in function name. Silly me. >.<

If I am reading that code correctly, that function doesn't need anything else from your post except itself, right? I could just copy it and paste it into gdip_imagesearch.ahk and it will work fine?
User avatar
noname
Posts: 515
Joined: 19 Nov 2013, 09:15

Re: Pixelsearch problem??

26 Mar 2018, 09:21

Hi MaxAstro , it only needs gdip library (gdip_all.ahk) .The gdip_imagesearch.ahk in my post is needed because it gives the comparison in speed between pixelsearch and imagesearch ( using a 1 pixel bitmap).

Here is an example i posted on another post , the hotkey to start search is ctrl+p

Code: Select all

#include *i gdip_all.ahk

SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1


If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}

;------------  demo window with colored point ---------------
    Gui,font,s28
    gui,add,text,c644E37,.
    gui,show, x50 y50 w100 h100 , demo
;------------  demo window  ---------------------------------

^p::
Coordmode, pixel
CoordMode, mouse

pBitmap:=Gdip_BitmapFromScreen("0|0|500|500")
Gdip_GetImageDimensions(pBitmap, w,h)

error:=Gdip_PixelSearch(pBitmap,0xff644E37,px,py)

If (Error < 0) {
Msgbox ERROR if %error%=-1 pixel not found
Gdip_DisposeImage(pBitmap)
return
}

MouseMove, %px%, %py%,

Gdip_DisposeImage(pBitmap)
return



guiclose:
esc::
Gdip_Shutdown(pToken)
ExitApp


Gdip_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y)
{
	static _PixelSearch
	if !_PixelSearch
	{
		MCode_PixelSearch := "8B44241099535583E2035603C233F6C1F80239742418577E388B7C24148B6C24248B5424188D1C85000000008D64240033C085"
		. "D27E108BCF3929743183C00183C1043BC27CF283C60103FB3B74241C7CDF8B4424288B4C242C5F5EC700FFFFFFFF5DC701FFFFFFFF83C8FF5BC38B4C2"
		. "4288B54242C5F890189325E5D33C05BC3"

		VarSetCapacity(_PixelSearch, StrLen(MCode_PixelSearch)//2)
		Loop % StrLen(MCode_PixelSearch)//2      ;%
			NumPut("0x" SubStr(MCode_PixelSearch, (2*A_Index)-1, 2), _PixelSearch, A_Index-1, "char")
	}
	Gdip_GetImageDimensions(pBitmap, Width, Height)
	if !(Width && Height)
		return -1

	if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
		return -2

	x := y := 0
	E := DllCall(&_PixelSearch, "uint", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int*", x, "int*", y)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -3 : E
}







guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: Pixelsearch problem??

28 Oct 2019, 00:08

noname wrote:
23 Mar 2018, 11:38
here is a comparison i made between gdip imagesearch and gdip pixelsearch both searching for 1 pixel.
both are showing 0 ms for me.. do you have any historic knowledge of which has worked faster for you?


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot] and 151 guests