Что нового

Поиск пикселей в определённой области при неактивном окне

blacklis

Новичок
Сообщения
64
Репутация
1
Добрый день. Извиняюсь, если вопрос уже обсуждался, в поиске ничего не нашёл
Есть ли аналог PixelSearch, ищущий пиксели в свёрнутом окне?
Всем спасибо
 

pussy

Новичок
Сообщения
28
Репутация
3
Re: Поиск пикселя в свёрнутом окне

В свернутом наверное никак, а в неактивном можно использовать параметр $hwnd
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

с $hwnd если окно перекрыто, он не находит :(
наткнулся на примеры с api_pixelgetcolor, но он возвращает цвет одного пикселя,а мне нужно в заданной площади.
Можно попробовать сделать цикл, который берёт каждый пиксель и сравнивает его цвет и при совпадении возвращает координаты, но это долго..
 

pussy

Новичок
Сообщения
28
Репутация
3
Re: Поиск пикселя в свёрнутом окне

http://autoit-script.ru/index.php/topic,1057.0.html
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

pussy,учитесь читать
Реализовал перебор пикселей на основе _PixelGetColorEx, всем спасибо.
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Re: Поиск пикселя в свёрнутом окне

blacklis
Попробуйте эту http://autoit-script.ru/index.php?topic=13686.msg92026#msg92026
Вроде и с перекрытыми работает и с "задвинутыми" и с прозрачными. Но не со свёрнутыми и не со скрытыми. Проверял на Win7.
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

При той же скорости ещё и возможность работы относительно клиентской области окна (по умолчанию относительно рабочего стола).
InnI, а как изменить на относительно клиента?

$hWnd = 0 заменить на $hWnd?
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Re: Поиск пикселя в свёрнутом окне

blacklis [?]
$hWnd = 0 заменить на $hWnd?
Верно. Передайте в функцию последним параметром handle вашего окна. Координаты будут рассчитаны относительно клиентской области этого окна.
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

InnI, вы не могли бы подсказать, как переделать вашу функцию, чтобы искала 1 нужный пиксель и возвращала его координаты при нахождении?
и за что отвечают $iWidth, $iHeight? Это ширина и высота прямоугольника, в котором ищутся пиксели?
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Re: Поиск пикселя в свёрнутом окне

blacklis [?]
чтобы искала 1 нужный пиксель и возвращала его координаты при нахождении
Для этого есть встроенная
Код:
PixelSearch()
Чем она вас не устраивает?

$iWidth, $iHeight? Это ширина и высота прямоугольника
$iWidth, $iHeight - это ширина и высота прямоугольника. :smile:
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

она не работает с перекрытым окном
а ваша функция прекрасно работает :smile:
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

ну выход то понятен,а вот возвращение координат? :stars:
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Re: Поиск пикселя в свёрнутом окне

blacklis [?]
возвращение координат
Так, ничего не изменилось. Раньше возвращались координаты всех точек, теперь только первой найденной.
Код:
$aPixels[1][0] ; X
$aPixels[1][1] ; Y
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

аа, он выдаёт координаты относительно прямоугольника
а координаты в окне получаются $aPixels[1][0] + $ix и тд
теперь всё понятно, спасибо тебе за отличную функцию! :beer:
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Re: Поиск пикселя в свёрнутом окне

Добавил пересчёт в координаты клиентской области.
Добавил параметр поиска только первого совпадения: $FirstOnly.
Код:
#include <Array.au3>
#include <WinAPIEx.au3>
#include <WindowsConstants.au3>

$t = TimerInit()
$test = _PixelGetArray(200, 200, 100, 100, 0x000000)
ConsoleWrite(TimerDiff($t) & @LF)
_ArrayDisplay($test)

Func _PixelGetArray($iX, $iY, $iWidth, $iHeight, $iColor, $hWnd = 0, $FirstOnly = False)
  Local $aPixels[$iWidth * $iHeight + 1][2]
  Local $hDC = _WinAPI_GetDC($hWnd)
  Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
  Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
  _WinAPI_SelectObject($hMemDC, $hBitmap)
  _WinAPI_BitBlt($hMemDC, 0, 0, $iWidth, $iHeight, $hDC, $iX, $iY, $SRCCOPY)
  _WinAPI_DeleteDC($hMemDC)
  _WinAPI_ReleaseDC($hWnd, $hDC)
  Local $iSize = $iWidth * $iHeight
  Local $tBits = DllStructCreate("dword[" & $iSize & "]")
  _WinAPI_GetBitmapBits($hBitmap, 4 * $iSize, DllStructGetPtr($tBits))
  Local $iCount = 0
  For $i = 1 To $iSize
    If BitAND(DllStructGetData($tBits, 1, $i), 0x00FFFFFF) = $iColor Then
      $iCount += 1
      $aPixels[$iCount][0] = Mod($i, $iWidth) - 1
      If $aPixels[$iCount][0] = -1 Then $aPixels[$iCount][0] = $iWidth - 1
      $aPixels[$iCount][1] = Ceiling($i / $iWidth) - 1
      If $FirstOnly Then ExitLoop
    EndIf
  Next
  ReDim $aPixels[$iCount + 1][2]
  $aPixels[0][0] = $iCount
  For $i = 1 To UBound($aPixels) - 1
    $aPixels[$i][0] += $iX
    $aPixels[$i][1] += $iY
  Next
  Return $aPixels
EndFunc   ;==>_PixelGetArray
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Re: Поиск пикселя в свёрнутом окне

в твоей функции не было никакой реакции, если пиксели не были найдены(или я её не нашёл)
Иногда может доставить неудобства :smile:
У себя в коде я добавил вот это:
Код:
...
 $aPixels[0][0] = $iCount
	if $iCount = 0 then  SetError(1) ;<==== 
    Return $aPixels
...

Может кому пригодится;)
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Re: Поиск пикселя в свёрнутом окне

Первый элемент массива содержит количество найденных пикселей. Это и есть "реакция". Если ноль - ничего не найдено ;)
Код:
$test = _PixelGetArray(200, 200, 100, 100, 0xffffff)
If Not $test[0][0] Then MsgBox(0, "", "Совпадений не найдено")
 
Автор
B

blacklis

Новичок
Сообщения
64
Репутация
1
Понятно :smile:
мне с @error как-то спокойней :D :-X
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
InnI,
Так меньше действий в цикле.
Код:
#include <Array.au3>
#include <WinAPIEx.au3>
#include <WindowsConstants.au3>

$t = TimerInit()
$test = _PixelGetArray(10, 10, 100, 100, 0xFFFFFF)
ConsoleWrite(TimerDiff($t) & @LF)
_ArrayDisplay($test)

Func _PixelGetArray($i_X, $i_Y, $i_Width, $i_Height, $i_Color, $h_Wnd = 0, $f_FirstOnly = False)
	Local $i_Size = $i_Width * $i_Height, $a_Pixels[$i_Size + 1][2] = [[0]], $h_DC, $h_MemDC, $h_Bitmap, $t_Bits, $i_Index

	;If Not $h_Wnd Then $h_Wnd = _WinAPI_GetShellWindow()
	$h_DC = _WinAPI_GetDC($h_Wnd)
	$h_MemDC = _WinAPI_CreateCompatibleDC($h_DC)
	$h_Bitmap = _WinAPI_CreateCompatibleBitmap($h_DC, $i_Width, $i_Height)
	_WinAPI_SelectObject($h_MemDC, $h_Bitmap)
	_WinAPI_BitBlt($h_MemDC, 0, 0, $i_Width, $i_Height, $h_DC, $i_X, $i_Y, $SRCCOPY)
	_WinAPI_DeleteDC($h_MemDC)
	_WinAPI_ReleaseDC($h_Wnd, $h_DC)
	$t_Bits = DllStructCreate('dword[' & $i_Size & ']')
	$p_Bits = DllStructGetPtr($t_Bits)
	_WinAPI_GetBitmapBits($h_Bitmap, 4 * $i_Size, $p_Bits)
	_WinAPI_DeleteObject($h_Bitmap)
	For $i = 0 To $i_Height - 1
		For $j = 0 To $i_Width - 1
			$i_Index += 1
			If BitAND(DllStructGetData($t_Bits, 1, $i_Index), 0x00FFFFFF) = $i_Color Then
				$a_Pixels[0][0] += 1
				$a_Pixels[$a_Pixels[0][0]][0] = $j + $i_X
				$a_Pixels[$a_Pixels[0][0]][1] = $i + $i_Y
				If $f_FirstOnly Then ExitLoop 2
			EndIf
		Next
	Next
	ReDim $a_Pixels[$a_Pixels[0][0] + 1][2]
	Return $a_Pixels
EndFunc   ;==>_PixelGetArray
 
Верх