Что нового

Аналог pixelgetcolor

Rivald

Новичок
Сообщения
61
Репутация
1
Как известно, функции pixelgetcolor и pixelsearch работают довольно медленно, что бывает очень занижает фпс, если говорить о каком-то дополнении, к игре например.
Я где-то видел тему где показано как можно использовать winapi для этого, там разница в скорости была почти в 10к раз, но найти эту тему не получилось, да и тогда я не смог приспособить тот пример под свои нужды. Хотелось бы узнать как сделать поиск пикселя или получение цвета через win API.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
Rivald [?]
можно использовать вин апи для этого
Предупреждение За нарушение общих правил (пункт В.8):
Так как эта конференция называется "Русское сообщество AutoIt", язык общения на ней - Русский. Названия фирм или программных продуктов, аббревиатуры и т.д. должны быть написаны так, как они пишутся в оригинале, например не следует писать УСБ вместо USB. На форуме крайне не рекомендуется намеренно искажать русский язык и использовать "сетевой жаргон" на подобии "Аффтар выпей йадау!".


С уважением, ваш Глобальный модератор.
 

Ganibal95

GreenBytes
Сообщения
877
Репутация
240
Rivald [?]
pixelgetcolor и pixelsearch

Это уже сделано в WinAPI и заложено в интерпретаторе...

Вот код который использует интерпретатор. С++
Код:
AUT_RESULT AutoIt_Script::F_PixelSearch (VectorVariant &vParams, Variant &vResult)
{
	uint		iNumParams = vParams.size();
	int			q,r;
	int			col;
	BYTE		red, green, blue;
	BYTE		red_low, red_high, green_low, green_high, blue_low, blue_high;
	HDC			hdc;
	RECT		relrect;
	int			nVar;
	int			nStep = 1;
	POINT		ptOrigin;

	relrect.left = vParams[0].nValue();
	relrect.top = vParams[1].nValue();
	relrect.right = vParams[2].nValue();
	relrect.bottom = vParams[3].nValue();

	// Convert coords to screen/active window/client
	ConvertCoords(m_nCoordPixelMode, ptOrigin);
	relrect.left += ptOrigin.x;
	relrect.top += ptOrigin.y;
	relrect.right += ptOrigin.x;
	relrect.bottom += ptOrigin.y;


	// Get the search colour and split into components
	col		= vParams[4].nValue();				// Pixel color to find
	if (m_bColorModeBGR == false)
		Util_RGBtoBGR(col);						// Get RGB color into the standard COLORREF BGR format

	red		= GetRValue(col);
	green	= GetGValue(col);
	blue	= GetBValue(col);

	// Variation required?
	if (iNumParams >= 6)
	{
		nVar = vParams[5].nValue();
		if ( nVar < 0 )
			nVar = 0;
		else if ( nVar > 0xff )
			nVar = 0xff;
	}
	else
		nVar = 0;

	// Step required?
	if (iNumParams >= 7 && vParams[6].nValue() > 1)
		nStep = vParams[6].nValue();

	// Config the variation code
	if (nVar == 0)								// Exact match
	{
		red_low = red_high = red;
		green_low = green_high = green;
		blue_low = blue_high = blue;
	}
	else
	{
		// Prevent wrap around
		red_low = (nVar > red) ? 0 : red - nVar;
		green_low = (nVar > green) ? 0 : green - nVar;
		blue_low = (nVar > blue) ? 0 : blue - nVar;
		red_high = (nVar > 0xFF - red) ? 0xFF : red + nVar;
		green_high = (nVar > 0xFF - green) ? 0xFF : green + nVar;
		blue_high = (nVar > 0xFF - blue) ? 0xFF : blue + nVar;
	}


	hdc = GetDC(NULL);

	for( q=relrect.left; q<=relrect.right; q = q + nStep)
	{
		for( r=relrect.top; r<=relrect.bottom; r = r + nStep)
		{
			col		= GetPixel(hdc, q, r);
			red		= GetRValue(col);
			green	= GetGValue(col);
			blue	= GetBValue(col);

			if (red >= red_low && red <= red_high && green >= green_low && green <= green_high
					&& blue >= blue_low && blue <= blue_high)
			{
				// Match!
				// Setup vResult as an Array to hold the 2 values we want to return
				Variant	*pvTemp;

				Util_VariantArrayDim(&vResult, 2);

				// Convert coords to screen/active window/client
				q -= ptOrigin.x;
				r -= ptOrigin.y;

				pvTemp = Util_VariantArrayGetRef(&vResult, 0);	//First element
				*pvTemp = q;					// X

				pvTemp = Util_VariantArrayGetRef(&vResult, 1);
				*pvTemp = r;					// Y

				ReleaseDC(NULL,hdc);

				return AUT_OK;
			}
		}
	}
	ReleaseDC(NULL,hdc);

	SetFuncErrorCode(1);			// Not found
	return AUT_OK;

} // PixelSearch()
 
Автор
R

Rivald

Новичок
Сообщения
61
Репутация
1
Обе функции _WinAPI_GetPixel и _PixelGetColor_GetPixelRaw возвращают ошибку -1.
Код:
#include <WinApiEx.au3>
$hwnd = WinGetHandle("***", '')
Sleep(5000)
Do
$color = _WinAPI_GetPixel($hwnd, 221, 908)
Until $color = "FF0000"


Код:
#include <_PixelGetColor.au3>
$hDll = DllOpen("gdi32.dll")
$vDC = _PixelGetColor_CreateDC($hDll)
Sleep(5000)
Do
$color = _PixelGetColor_GetPixelRaw($vDC, 221, 908, $hDll)
Until $color = "FF0000"
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
365
Rivald
Первый код точно неправильный

Должно быть что-то вроде:
Код:
#include <WinAPIEx.au3>

$hDC = _WinAPI_GetDC(0)

For $y = 0 To 10 Step 1
	For $x = 0 To 10 Step 1
		$pixel = _WinAPI_GetPixel($hDC, $x, $y)
		ConsoleWrite('0x' & Hex($pixel, 6) & @CRLF)
	Next
Next

_WinAPI_ReleaseDC(0, $hDC)


Второй код не сильно лучше обычного PixelGetColor-а

Недавно обсуждали на эту тему:
http://autoit-script.ru/index.php/topic,13686.0.html
вот там - одни из самых быстрых вариантов, конечно, смотря, что нужно получить.
 
Автор
R

Rivald

Новичок
Сообщения
61
Репутация
1
Почему же, второй код весьма быстрее работает:
Starting test in field (0,0) to (10,10)
Native: 68.2394146416851
UDF : 5.25145225952491.
И зачем мне в 1 функции искать цвет 10 раз, когда мне нужны координаты 1 конкретной точки?
 
Верх