Gdip_PixelSearch Wont Work :(

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 23 Oct 2021, 18:29

malcev wrote:
20 Oct 2021, 21:58
Searching using machine code

Code: Select all

setbatchlines -1
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen()
if !Gdip_PixelSearch(pBitmap, ARGB := 0xFF336EA5, x, y, 30)
   MsgBox, Pixel %ARGB% found at (%x%, %y%)
else
   MsgBox, Pixel %ARGB% not found
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

;#####################################################################################

Gdip_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y, variation)
{
	static MCode_PixelSearch
	if !MCode_PixelSearch
           MCode_PixelSearch := MCode("2,x86:VVdWU4PsEItMJDCLRCQ0i3QkOIXJjVEDD0nRi0wkLMH6AoXJD46RAAAAicEPtvzHRCQIAAAAAA+26MH5EIk8JA+2+Yl8JASNPJUAAAAAiXwkDIt8JCSLRCQoMcmFwH5IixSPD7bCKeiJw8H7HzHYKdg58H8qD7bGKwQkicPB+x8x2CnYOfB/F8HqEA+20itUJASJ0MH4HzHCKcI58n5Bg8EBOUwkKHW4g0QkCAEDfCQMi0QkCDlEJCx1m4tEJDzHAP////+LRCRAxwD/////g8QQuP////9bXl9dw410JgCLRCQ8i3wkCIkIi0QkQIk4g8QQMcBbXl9dww==,x64:QVdBVkFVQVRVV1ZTSIPsGESLlCSIAAAARYXJQY1BA0GJ1UmJzEQPSMiLlCSAAAAARYnGQcH5AkSJTCQMRYXAD46KAAAAidcPtvZFMf8x7cH/EEQPttpJY91AD7b/RYXtfmBJY8cxyU2NDIQPH0QAAEGLFIkPtsJEKdhBicBBwfgfRDHARCnARDnQfy0PtsYp8EGJwEHB+B9EMcBEKcBEOdB/FsHqEA+20in6idDB+B8xwinCRDnSfj9Ig8EBSDnLda6DxQFEA3wkDEE57nWOSIuEJJAAAADHAP////9Ii4QkmAAAAMcA/////7j/////6xxmDx9EAABIi4QkkAAAAIkISIuEJJgAAACJKDHASIPEGFteX11BXEFdQV5BX8M=")
	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(MCode_PixelSearch, "ptr", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int", variation, "int*", x, "int*", y)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -3 : E
}

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}
c++ function (c++ I dont know much)

Code: Select all

int Gdip_PixelSearch(unsigned int* HayStack, int w, int h, int Stride, int ARGB, int variation, int* x, int* y)
{
	int var;
	int offset = Stride / 4;
	for (int y1 = 0; y1 < h; ++y1)
	{
		for (int x1 = 0; x1 < w; ++x1)
		{
			var = (HayStack[x1 + (y1 * offset)] & 0xff) - (ARGB & 0xff);
			if (abs(var) <= variation)
			{
				var = ((HayStack[x1 + (y1 * offset)] >> 8) & 0xff) - ((ARGB >> 8) & 0xff);
				if (abs(var) <= variation)
				{
					var = ((HayStack[x1 + (y1 * offset)] >> 16) & 0xff) - ((ARGB >> 16) & 0xff);
					if (abs(var) <= variation)
					{
						x[0] = x1; y[0] = y1;
						return 0;
					}
				}
			}
		}
	}
	x[0] = -1; y[0] = -1;
	return -1;
}
what do i need to learn to write code this way?
for me it doesn't make any sense the way the symbols are organized...

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Gdip_PixelSearch Wont Work :(

Post by malcev » 23 Oct 2021, 20:42

wanted to script this way with GDIP:
identify the color of the pixel under the mouse pointer
Read about GDIP_GetPixel.
what do i need to learn to write code this way?
Basic c++ knowledge + algorithm of searching.
is there any way to change the coordinate mode to "Screen" instead of "Window"(default)?
After receiving coordinates from Gdip_PixelSearch, modify them relative to window position.

User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 23 Oct 2021, 22:54

Read about GDIP_GetPixel.
I analyzed GDIP_GETPIXEL, but is returning a strange value ... I think I need to set the format, I put "setformat, integer, h" in the function and returned correctly the value, but I think this is not the best way to do. What would be the other?
MyScript:

Code: Select all

	; [ LIBRARY ]
	#Include Gdip.ahk
	
	pToken := Gdip_Startup()
	pBitmap := Gdip_BitmapFromHWND( WinExist("Paint") )
	msgbox % Gdip_GetPixel( pBitmap, 116, 215 )
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown(pToken)
/break
/break
After receiving coordinates from Gdip_PixelSearch, modify them relative to window position.
Is there a way to modify this value without being using the "Coordmode" command?.
If so, can you give an example?

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Gdip_PixelSearch Wont Work :(

Post by malcev » 24 Oct 2021, 07:46

I think I need to set the format,
It returns argb format in decimal system.
You dont need to convert it.
Is there a way to modify this value without being using the "Coordmode" command?.
You dont need coordmode.
If Your returned value is relative to window then to convert it to be relative to screen You need

Code: Select all

foundX := 50
WinGetPos, x, y,,, Your app
foundX+=x

User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 24 Oct 2021, 17:59

Is there a way to modify this value without being using the "Coordmode" command?.
You dont need coordmode.
If Your returned value is relative to window then to convert it to be relative to screen You need

Code: Select all

foundX := 50
WinGetPos, x, y,,, Your app
foundX+=x
what if it was the other way around?
and if I want to transform a screen coordinate into a window coordinate?

User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: Gdip_PixelSearch Wont Work :(

Post by boiler » 24 Oct 2021, 18:09

ibieel wrote: what if it was the other way around?
and if I want to transform a screen coordinate into a window coordinate?
Use WinGetPos to determine the x and y coordinates of the window of interest and subtract those from the screen x and y coordinates. The result will be the coordinates relative to that window.

User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 24 Oct 2021, 18:16

malcev wrote:
24 Oct 2021, 07:46
I think I need to set the format,
It returns argb format in decimal system.
You dont need to convert it.
ok, really, it looks like it worked. I didn't need to convert.
but how could i do to convert this value?
I put this command and it worked:

Code: Select all

SetFormat, Integer, H
but I think there are better ways, because the documentation said not to use it :(

User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: Gdip_PixelSearch Wont Work :(

Post by boiler » 24 Oct 2021, 19:58

Use the Format() function to display a value in hex. However, it only matters for display purposes. You are not actually changing or converting the value. You are just choosing the form in which to display it. For example, the decimal value 10 and hex value 0xA are equivalent no matter how they are displayed. As a demonstration:

Code: Select all

Num := 10
if (Num = 0xA)
	MsgBox, They are equal

User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 24 Oct 2021, 20:17

boiler wrote:
24 Oct 2021, 19:58
Use the Format() function to display a value in hex. However, it only matters for display purposes. You are not actually changing or converting the value. You are just choosing the form in which to display it. For example, the decimal value 10 and hex value 0xA are equivalent no matter how they are displayed. As a demonstration:

Code: Select all

Num := 10
if (Num = 0xA)
	MsgBox, They are equal

but it looks like my script doesn't recognize the color correctly if it's not in the format like this: 0x00CC00
I've tried it in several ways, it seems that "0xFF00CC00" is different.
can you help me with a function to transform the decimal value into hex?

this code below would work if the values were in hex.

Code: Select all

Gui, Cor:New
Gui, +AlwaysOnTop +Resize
Gui, Cor:Show, % " w" 270 " h" 270, VERIFY COLOR
Loop, {
		MouseGetPos, MouseX, MouseY
		;PixelGetColor, cor2, %MouseX%, %MouseY%, RGB
		cor2 := Gdip_GetPixel( pBitmap, MouseX,MouseY )
		Gui, Cor:Color, %cor2%
}

User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: Gdip_PixelSearch Wont Work :(

Post by boiler » 24 Oct 2021, 20:39

No, it has nothing to do with the format, and I won’t help you transform the value from decimal to hex because they are not different values. There is no such thing as converting it to hex so it can be compared to other hex numbers. They’re all just unitless integers that can be displayed for humans using either the decimal numbering system or the hexadecimal numbering system (or some other). It doesn’t change the number or how AHK compares it. It’s not like converting inches to cm where they have different units. They are the same number, and you aren’t converting its internal representation. Things like Format() are only for displaying that same value in one form or another.

The reason 0xFF00CC00 and 0x00CC00 are not equivalent has nothing to do with format. They are different numbers. One contains the alpha channel as the FF (FF representing fully opaque, while 00 would be fully transparent), and the other doesn’t. If you need to add the FF as the alpha channel value to an RGB color value to make an ARGB color value, then you do it like this:

Code: Select all

ColorARGB := ColorRGB | 0xFF000000
If you want to strip off the alpha channel from an ARGB color value to make an RGB color value (i.e., without the alpha channel), then you do it like this:

Code: Select all

ColorRGB := ColorARGB & 0xFFFFFF

When comparing color values, you have to compare apples to apples. You have to know if your reference color value contains the alpha channel or not, and the value you are comparing it to then must also either include it or not depending on the reference.

User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 25 Oct 2021, 01:23

boiler wrote:
24 Oct 2021, 20:39
No, it has nothing to do with the format, and I won’t help you transform the value from decimal to hex because they are not different values. There is no such thing as converting it to hex so it can be compared to other hex numbers. They’re all just unitless integers that can be displayed for humans using either the decimal numbering system or the hexadecimal numbering system (or some other). It doesn’t change the number or how AHK compares it. It’s not like converting inches to cm where they have different units. They are the same number, and you aren’t converting its internal representation. Things like Format() are only for displaying that same value in one form or another.

The reason 0xFF00CC00 and 0x00CC00 are not equivalent has nothing to do with format. They are different numbers. One contains the alpha channel as the FF (FF representing fully opaque, while 00 would be fully transparent), and the other doesn’t. If you need to add the FF as the alpha channel value to an RGB color value to make an ARGB color value, then you do it like this:

Code: Select all

ColorARGB := ColorRGB | 0xFF000000
If you want to strip off the alpha channel from an ARGB color value to make an RGB color value (i.e., without the alpha channel), then you do it like this:

Code: Select all

ColorRGB := ColorARGB & 0xFFFFFF

When comparing color values, you have to compare apples to apples. You have to know if your reference color value contains the alpha channel or not, and the value you are comparing it to then must also either include it or not depending on the reference.
I understand that they are different characters for the representation of a color.
however, in the autohotkey GUI documentation (Gui, Color) it needs 6-digit RGB color value to work correctly.
I used the Format() function (to transform decimal in hex) and SubStr() (to remove the "FF" from the beginning). It worked

phoenixL337
Posts: 12
Joined: 17 Oct 2021, 04:30

Re: Gdip_PixelSearch Wont Work :(

Post by phoenixL337 » 27 Oct 2021, 05:24

ibieel wrote:
23 Oct 2021, 18:28
malcev wrote:
20 Oct 2021, 21:58
Searching using machine code

Code: Select all

setbatchlines -1
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen()
if !Gdip_PixelSearch(pBitmap, ARGB := 0xFF336EA5, x, y, 30)
   MsgBox, Pixel %ARGB% found at (%x%, %y%)
else
   MsgBox, Pixel %ARGB% not found
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

;#####################################################################################

Gdip_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y, variation)
{
	static MCode_PixelSearch
	if !MCode_PixelSearch
           MCode_PixelSearch := MCode("2,x86:VVdWU4PsEItMJDCLRCQ0i3QkOIXJjVEDD0nRi0wkLMH6AoXJD46RAAAAicEPtvzHRCQIAAAAAA+26MH5EIk8JA+2+Yl8JASNPJUAAAAAiXwkDIt8JCSLRCQoMcmFwH5IixSPD7bCKeiJw8H7HzHYKdg58H8qD7bGKwQkicPB+x8x2CnYOfB/F8HqEA+20itUJASJ0MH4HzHCKcI58n5Bg8EBOUwkKHW4g0QkCAEDfCQMi0QkCDlEJCx1m4tEJDzHAP////+LRCRAxwD/////g8QQuP////9bXl9dw410JgCLRCQ8i3wkCIkIi0QkQIk4g8QQMcBbXl9dww==,x64:QVdBVkFVQVRVV1ZTSIPsGESLlCSIAAAARYXJQY1BA0GJ1UmJzEQPSMiLlCSAAAAARYnGQcH5AkSJTCQMRYXAD46KAAAAidcPtvZFMf8x7cH/EEQPttpJY91AD7b/RYXtfmBJY8cxyU2NDIQPH0QAAEGLFIkPtsJEKdhBicBBwfgfRDHARCnARDnQfy0PtsYp8EGJwEHB+B9EMcBEKcBEOdB/FsHqEA+20in6idDB+B8xwinCRDnSfj9Ig8EBSDnLda6DxQFEA3wkDEE57nWOSIuEJJAAAADHAP////9Ii4QkmAAAAMcA/////7j/////6xxmDx9EAABIi4QkkAAAAIkISIuEJJgAAACJKDHASIPEGFteX11BXEFdQV5BX8M=")
	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(MCode_PixelSearch, "ptr", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int", variation, "int*", x, "int*", y)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -3 : E
}

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}
c++ function (c++ I dont know much)

Code: Select all

int Gdip_PixelSearch(unsigned int* HayStack, int w, int h, int Stride, int ARGB, int variation, int* x, int* y)
{
	int var;
	int offset = Stride / 4;
	for (int y1 = 0; y1 < h; ++y1)
	{
		for (int x1 = 0; x1 < w; ++x1)
		{
			var = (HayStack[x1 + (y1 * offset)] & 0xff) - (ARGB & 0xff);
			if (abs(var) <= variation)
			{
				var = ((HayStack[x1 + (y1 * offset)] >> 8) & 0xff) - ((ARGB >> 8) & 0xff);
				if (abs(var) <= variation)
				{
					var = ((HayStack[x1 + (y1 * offset)] >> 16) & 0xff) - ((ARGB >> 16) & 0xff);
					if (abs(var) <= variation)
					{
						x[0] = x1; y[0] = y1;
						return 0;
					}
				}
			}
		}
	}
	x[0] = -1; y[0] = -1;
	return -1;
}
WTF ?!
I can't understand any of this code...
what does that mean?

Code: Select all

  MCode_PixelSearch := MCode("2,x86:VVdWU4PsEItMJDCLRCQ0i3QkOIXJjVEDD0nRi0wkLMH6AoXJD46RAAAAicEPtvzHRCQIAAAAAA+26MH5EIk8JA+2+Yl8JASNPJUAAAAAiXwkDIt8JCSLRCQoMcmFwH5IixSPD7bCKeiJw8H7HzHYKdg58H8qD7bGKwQkicPB+x8x2CnYOfB/F8HqEA+20itUJASJ0MH4HzHCKcI58n5Bg8EBOUwkKHW4g0QkCAEDfCQMi0QkCDlEJCx1m4tEJDzHAP////+LRCRAxwD/////g8QQuP////9bXl9dw410JgCLRCQ8i3wkCIkIi0QkQIk4g8QQMcBbXl9dww==,x64:QVdBVkFVQVRVV1ZTSIPsGESLlCSIAAAARYXJQY1BA0GJ1UmJzEQPSMiLlCSAAAAARYnGQcH5AkSJTCQMRYXAD46KAAAAidcPtvZFMf8x7cH/EEQPttpJY91AD7b/RYXtfmBJY8cxyU2NDIQPH0QAAEGLFIkPtsJEKdhBicBBwfgfRDHARCnARDnQfy0PtsYp8EGJwEHB+B9EMcBEKcBEOdB/FsHqEA+20in6idDB+B8xwinCRDnSfj9Ig8EBSDnLda6DxQFEA3wkDEE57nWOSIuEJJAAAADHAP////9Ii4QkmAAAAMcA/////7j/////6xxmDx9EAABIi4QkkAAAAIkISIuEJJgAAACJKDHASIPEGFteX11BXEFdQV5BX8M=")
but it seems to be working...


can I change the "Width, Height" parameters to choose which area of the screen I want to search?

is there any way to change the coordinate mode to "Screen" instead of "Window"(default)?



is there any way to know the pixel of the X,Y coordinate?
instead of looking for the color pixel, know what the color of the coordinate pixel
using GDIP

wanted to script this way with GDIP:
identify the color of the pixel under the mouse pointer


Code: Select all

MouseGetPos, MouseX, MouseY
PixelGetColor, ColorID, %MouseX%, %MouseY%
ToolTip, %ColorID%

Code: Select all

global win_title:="Untitled - Notepad"
pBitmap := Gdip_BitmapFromHWND(WinExist(win_title))

; if needed get area of bitmap for search
x:=20 , y:=20 ,w:=100 ,h:=100

area_bitmap:=Gdip_CloneBitmapArea(pBitmap, x, y, w, h)

;color to search for
argb:=0xff28f028  

Gdip_PixelSearch(area_bitmap,argb, posx, posy)

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Gdip_PixelSearch Wont Work :(

Post by malcev » 27 Oct 2021, 12:22

You dont need Gdip_CloneBitmapArea.

User avatar
ibieel
Posts: 216
Joined: 17 Oct 2021, 23:30

Re: Gdip_PixelSearch Wont Work :(

Post by ibieel » 02 Sep 2022, 18:44

malcev wrote:
20 Oct 2021, 21:58
Searching using machine code

Code: Select all

setbatchlines -1
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen()
if !Gdip_PixelSearch(pBitmap, ARGB := 0xFF336EA5, x, y, 30)
   MsgBox, Pixel %ARGB% found at (%x%, %y%)
else
   MsgBox, Pixel %ARGB% not found
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

;#####################################################################################

Gdip_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y, variation)
{
	static MCode_PixelSearch
	if !MCode_PixelSearch
           MCode_PixelSearch := MCode("2,x86:VVdWU4PsEItMJDCLRCQ0i3QkOIXJjVEDD0nRi0wkLMH6AoXJD46RAAAAicEPtvzHRCQIAAAAAA+26MH5EIk8JA+2+Yl8JASNPJUAAAAAiXwkDIt8JCSLRCQoMcmFwH5IixSPD7bCKeiJw8H7HzHYKdg58H8qD7bGKwQkicPB+x8x2CnYOfB/F8HqEA+20itUJASJ0MH4HzHCKcI58n5Bg8EBOUwkKHW4g0QkCAEDfCQMi0QkCDlEJCx1m4tEJDzHAP////+LRCRAxwD/////g8QQuP////9bXl9dw410JgCLRCQ8i3wkCIkIi0QkQIk4g8QQMcBbXl9dww==,x64:QVdBVkFVQVRVV1ZTSIPsGESLlCSIAAAARYXJQY1BA0GJ1UmJzEQPSMiLlCSAAAAARYnGQcH5AkSJTCQMRYXAD46KAAAAidcPtvZFMf8x7cH/EEQPttpJY91AD7b/RYXtfmBJY8cxyU2NDIQPH0QAAEGLFIkPtsJEKdhBicBBwfgfRDHARCnARDnQfy0PtsYp8EGJwEHB+B9EMcBEKcBEOdB/FsHqEA+20in6idDB+B8xwinCRDnSfj9Ig8EBSDnLda6DxQFEA3wkDEE57nWOSIuEJJAAAADHAP////9Ii4QkmAAAAMcA/////7j/////6xxmDx9EAABIi4QkkAAAAIkISIuEJJgAAACJKDHASIPEGFteX11BXEFdQV5BX8M=")
	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(MCode_PixelSearch, "ptr", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int", variation, "int*", x, "int*", y)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -3 : E
}

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}
c++ function (c++ I dont know much)

Code: Select all

int Gdip_PixelSearch(unsigned int* HayStack, int w, int h, int Stride, int ARGB, int variation, int* x, int* y)
{
	int var;
	int offset = Stride / 4;
	for (int y1 = 0; y1 < h; ++y1)
	{
		for (int x1 = 0; x1 < w; ++x1)
		{
			var = (HayStack[x1 + (y1 * offset)] & 0xff) - (ARGB & 0xff);
			if (abs(var) <= variation)
			{
				var = ((HayStack[x1 + (y1 * offset)] >> 8) & 0xff) - ((ARGB >> 8) & 0xff);
				if (abs(var) <= variation)
				{
					var = ((HayStack[x1 + (y1 * offset)] >> 16) & 0xff) - ((ARGB >> 16) & 0xff);
					if (abs(var) <= variation)
					{
						x[0] = x1; y[0] = y1;
						return 0;
					}
				}
			}
		}
	}
	x[0] = -1; y[0] = -1;
	return -1;
}
@malcev
Could you help me in an edit in this function?
I would like to search the pixel for a certain area, not the entire screen. I made a change, but it seems to be giving problems in some cases.
i used AutoHotkeyU32 to exec this script.
my computer 64bits work normally, but my laptop 32bits no :(

in:

Code: Select all

E := DllCall(MCode_PixelSearch, "ptr", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int", variation, "int*", x, "int*", y)
MsgBox, E ErrorLevel=%ErrorLevel%
the return of E ErrorLevel is "0xc0000005"

Code: Select all


PixelSrch := Gdip_PixelSearch(Bitmap, "0xFF000000", "OutputVarPSX","OutputVarPSY", 500,500,5,5, 35)

;#####################################################################################
Gdip_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y, PosX,PosY,Width,Height, variation)
{
	static MCode_PixelSearch := ""
	if !MCode_PixelSearch
           MCode_PixelSearch := MCode("2,x86:VVdWU4PsEItMJDCLRCQ0i3QkOIXJjVEDD0nRi0wkLMH6AoXJD46RAAAAicEPtvzHRCQIAAAAAA+26MH5EIk8JA+2+Yl8JASNPJUAAAAAiXwkDIt8JCSLRCQoMcmFwH5IixSPD7bCKeiJw8H7HzHYKdg58H8qD7bGKwQkicPB+x8x2CnYOfB/F8HqEA+20itUJASJ0MH4HzHCKcI58n5Bg8EBOUwkKHW4g0QkCAEDfCQMi0QkCDlEJCx1m4tEJDzHAP////+LRCRAxwD/////g8QQuP////9bXl9dw410JgCLRCQ8i3wkCIkIi0QkQIk4g8QQMcBbXl9dww==,x64:QVdBVkFVQVRVV1ZTSIPsGESLlCSIAAAARYXJQY1BA0GJ1UmJzEQPSMiLlCSAAAAARYnGQcH5AkSJTCQMRYXAD46KAAAAidcPtvZFMf8x7cH/EEQPttpJY91AD7b/RYXtfmBJY8cxyU2NDIQPH0QAAEGLFIkPtsJEKdhBicBBwfgfRDHARCnARDnQfy0PtsYp8EGJwEHB+B9EMcBEKcBEOdB/FsHqEA+20in6idDB+B8xwinCRDnSfj9Ig8EBSDnLda6DxQFEA3wkDEE57nWOSIuEJJAAAADHAP////9Ii4QkmAAAAMcA/////7j/////6xxmDx9EAABIi4QkkAAAAIkISIuEJJgAAACJKDHASIPEGFteX11BXEFdQV5BX8M=")
	;Gdip_GetImageDimensions(pBitmap, Width, Height)
	;if !(Width && Height)
	;	return -1
	
	if (E1 := Gdip_LockBits(pBitmap, PosX, PosY, Width, Height, Stride1, Scan01, BitmapData1))
		return -2

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

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86", s := "", op := ""
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}


william_ahk
Posts: 482
Joined: 03 Dec 2018, 20:02

Re: Gdip_PixelSearch Wont Work :(

Post by william_ahk » 27 Feb 2023, 07:00

@malcev I tried loading bitmap from a png file and the colors are zero. How do you write it so that it can read png images?

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Gdip_PixelSearch Wont Work :(

Post by malcev » 27 Feb 2023, 07:11

Gdip_CreateBitmapFromFile

william_ahk
Posts: 482
Joined: 03 Dec 2018, 20:02

Re: Gdip_PixelSearch Wont Work :(

Post by william_ahk » 27 Feb 2023, 10:28

Sorry I figured out what's wrong. I was using msgbox to output pixel colors and msgbox can't show too much text, plus the transparent pixels in png led me to believe that all colors are zero. Human error once again :facepalm:

Post Reply

Return to “Ask for Help (v1)”