Что нового

Поиск всех координат одного цвета

peter911

Новичок
Сообщения
18
Репутация
0
Версия AutoIt: 3.3.8.1/3.3.9.4

Описание: Так же нужно найти минимальное расстояние
cb67zwl8c9es.png

Примечания: Нашел http://autoit-script.ru/index.php/topic,5887.0.html http://autoit-script.ru/index.php/topic,8577.0.html
Но алгоритм очень медленный
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
peter911

Что значит алгоритм медленный? А как быстро нужно (в секундах)?
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
Не более половины секунды. Но не полчаса.

Мне видится алгоритм поиска по спирали(вокруг т. (Cx; Cy)), но GetPixel очень медленный, нельзя как быстрей сделать?

То есть я не верно задал тему. Нужно только первую ближайшую точку найти.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
peter911

Искать нужно в каком-то окне, или на всем экране?

Для начала вот код, который находит координаты всех пикселей указанного цвета в указанной области экрана:

Код:
#include <Array.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>


$timer = TimerInit()
$Color = '860CFF' ; цвет без '0x'

$aMatrix = _DesktopMatrix($Color)
ConsoleWrite(TimerDiff($timer) & @CR)

_ArrayDisplay($aMatrix, $Color)

Func _DesktopMatrix($sColor)
	Local $hBmp, $hBitmap2, $tMap, $bData2, $Width, $Height, $n = 0
	_GDIPlus_Startup()
	$hBmp = _ScreenCapture_Capture('', 0, 0, 500, 500)  ; координаты прямоугольника скриншота
	$hBitmap2 = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
	$Width = _GDIPlus_ImageGetWidth($hBitmap2) - 1
	$Height = _GDIPlus_ImageGetHeight($hBitmap2) - 1
	$tMap = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	$bData2 = DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData($tMap, 'Scan0')), 1)
	_GDIPlus_BitmapUnlockBits($hBitmap2, $tMap)
	_GDIPlus_BitmapDispose($hBitmap2)
	_GDIPlus_Shutdown()
	
	$bData2 = '######FF' & StringTrimLeft($bData2, 2)
	
	$sColor = StringRegExpReplace($sColor, '(.{2})(.{2})(.{2})', '\3\2\1')

	$ext = StringRegExp($bData2, $sColor, 3)
	
	If Ubound($ext) - 1 > 0 Then		
		$aTemp = StringRegExp($bData2, '(\S{6})FF', 3)
		
		Dim $uArray[Ubound($ext)][2] = [[0]]
		
		For $i = 0 To UBound($aTemp) - 1
			If $aTemp[$i] = $sColor Then
				$y = Floor($i / ($Width))
				$x = ($i - $y * $Width)
				$uArray[$n][0] = $x
				$uArray[$n][1] = $y
				$n += 1				
			EndIf
		Next
	Else
		Return SetError(1, 0, 0)
	EndIf	
	
	Return $uArray

EndFunc   ;==>_DesktopMatrix1


Чем меньше пикселей этого цвета, и чем меньше площадь поиска, тем быстрее работает.

На счет минимального расстояния - несмотря на то, что когда-то и в математических олимпиадах участвовал, сейчас геометрия полностью выветрилась из головы... )
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
Спс за код, сейчас попробую. Расстояние очень легко считается, но можно не считать, если искать по спирали


Добавлено:
Сообщение автоматически объединено:

Да. Мне нужно в окне искать
Все работает очень быстро в чем секрет?
Только искал FFFFFF и с 2803 индекса идут пустые col 0, col 1 без координат.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
peter911

Как раз с FFFFFF могут быть ошибки, и это все как раз из-за принципа работы этого метода. Изображение с экрана копируется прямо в память, и представляется там как текстовая строка, которую можно обработать регулярными выражениями - а они в Autoit одни из самых быстрых функций.

Строка кода
Код:
$ext = StringRegExp($bData2, $sColor, 3)

просто и быстро определяет примерный размер массива - сколько элементов FFFFFF в строке $bData2.

Строка эта может быть вида
FFDFD1B2FFDFD3B2FFDFD1B1 и т.д.
где сразу видно, что FF отделяют один пиксель от другого

Но из-за того, что там могут быть и сочетания типа:
FFDFFFFFFFDFD1B2FFFFFFB1 и т.д.
при $sColor = FFFFFF StringRegExp дает большее количество элементов, чем на самом деле есть пикселей белого цвета, и итоговый массив получается частично пустой.

Лучше, конечно, искать какой-нибудь уникальный цвет.

Вот другой вариант, но он может быть медленнее, т.к. там используется функция
Код:
_ArrayFindAll
и в итоге получается 2 цикла вместо 1.

Код:
#include <Array.au3>
#include <GDIP.au3>
#include <ScreenCapture.au3>


$timer = TimerInit()
$Color = 'FFFFFF' ; цвет без '0x'

$aMatrix = _DesktopMatrix1($Color)
ConsoleWrite(TimerDiff($timer) & @CR)

_ArrayDisplay($aMatrix, $Color)

Func _DesktopMatrix1($sColor)
	Local $hBmp, $hBitmap2, $tMap, $bData2, $Width, $Height
	_GDIPlus_Startup()
	$hBmp = _ScreenCapture_Capture('', 0, 0, 500, 500) ; координаты прямоугольника скриншота	
	$hBitmap2 = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
	$Width = _GDIPlus_ImageGetWidth($hBitmap2) - 1
	$Height = _GDIPlus_ImageGetHeight($hBitmap2) - 1
	$tMap = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	$bData2 = DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData($tMap, 'Scan0')), 1)
	
	_GDIPlus_BitmapUnlockBits($hBitmap2, $tMap)
	_GDIPlus_BitmapDispose($hBitmap2)
	_GDIPlus_Shutdown()
	
	$bData2 = '######FF' & StringTrimLeft($bData2, 2)
	$sColor = StringRegExpReplace($sColor, '(.{2})(.{2})(.{2})', '\3\2\1')
	
	If StringInStr($bData2, $sColor) Then
		
		$aTemp = StringRegExp($bData2, '(\S{6})FF', 3)
		
		$aiResult = _ArrayFindAll($aTemp, $sColor)
		If $aiResult <> -1 Then
			Dim $uArray[UBound($aiResult)][2] = [[0]]
			For $i = 0 To UBound($aiResult) - 1
				$y = Floor($aiResult[$i] / ($Width))
				$x = ($aiResult[$i] - $y * $Width)
				$uArray[$i][0] = $x
				$uArray[$i][1] = $y
			Next
		Else
			Return SetError(1, 0, 0)
		EndIf
		
		Return $uArray
		
	Else
		Return SetError(1, 0, 0)
	EndIf
EndFunc   ;==>_DesktopMatrix
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
WSWR [?]
Как раз с FFFFFF могут быть ошибки
Попробуйте поменять на
Код:
;...
$sColor = StringRegExpReplace($sColor, '(.{2})(.{2})(.{2})', '\3\2\1FF')
$aTemp = StringRegExp($bData2, '.{8}', 3)
;...
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
WSWR работает, время выполнения увеличилось с 0.8 до 1.0
madmasles ничего не изменилось


Добавлено:
Сообщение автоматически объединено:

Есть какие-либо алгоритмы для объединения соседних пикселей в одну точку?
 

madmasles

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


$timer = TimerInit()
$Color = 'FFFFFF' ; цвет без '0x'

$aMatrix = _DesktopMatrix1($Color)
ConsoleWrite(TimerDiff($timer) & @CR)

_ArrayDisplay($aMatrix, $Color)

Func _DesktopMatrix1($sColor)
    Local $hBmp, $hBitmap2, $tMap, $bData2, $Width, $Height
    _GDIPlus_Startup()
    $hBmp = _ScreenCapture_Capture('', 0, 0, 10, 10) ; координаты прямоугольника скриншота
    $hBitmap2 = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
    $Width = _GDIPlus_ImageGetWidth($hBitmap2) - 1
    $Height = _GDIPlus_ImageGetHeight($hBitmap2) - 1
    $tMap = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $bData2 = DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData($tMap, 'Scan0')), 1)

    _GDIPlus_BitmapUnlockBits($hBitmap2, $tMap)
    _GDIPlus_BitmapDispose($hBitmap2)
    _GDIPlus_Shutdown()

    $bData2 = '######FF' & StringTrimLeft($bData2, 2)
    $sColor = StringRegExpReplace($sColor, '(.{2})(.{2})(.{2})', '\3\2\1')

    If StringInStr($bData2, $sColor) Then

        $aTemp = StringRegExp($bData2, '(\S{6})FF', 3)

        $aiResult = _ArrayFindAll($aTemp, $sColor)
        If $aiResult <> -1 Then
            Dim $uArray[UBound($aiResult)][3] = [[0]]
            For $i = 0 To UBound($aiResult) - 1
                $y = Floor($aiResult[$i] / ($Width))
                $x = ($aiResult[$i] - $y * $Width)
                $uArray[$i][0] = $x
                $uArray[$i][1] = $y
				$uArray[$i][2] = Hex(PixelGetColor($x, $y), 6)
            Next
        Else
            Return SetError(1, 0, 0)
        EndIf

        Return $uArray

    Else
        Return SetError(1, 0, 0)
    EndIf
EndFunc   ;==>_DesktopMatrix
Так, вроде, правильно.
Код:
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <Array.au3>

Local $sColor = 'FFFFFF', $aRet[1]
_GDIPlus_Startup()
$hBmp = _ScreenCapture_Capture('', 0, 0, 10, 10)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
$iWidth = _GDIPlus_ImageGetWidth($hBitmap) - 1
$iHeight = _GDIPlus_ImageGetHeight($hBitmap) - 1
$tMap = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
$sData = Hex(DllStructGetData(DllStructCreate('byte[' & ($iWidth * $iHeight * 4) & ']', DllStructGetData($tMap, 'Scan0')), 1))
_GDIPlus_BitmapUnlockBits($hBitmap, $tMap)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()
$sTmpColor = StringRegExpReplace($sColor, '(.{2})(.{2})(.{2})', '\3\2\1FF')
$aTemp = StringRegExp($sData, '.{8}', 3)
ReDim $aRet[UBound($aTemp) + 1][3]
For $i = 0 To UBound($aTemp) - 1
	If $aTemp[$i] = $sTmpColor Then
		$aRet[0][0] += 1
		$aRet[$aRet[0][0]][1] = Floor($i / ($iWidth))
		$aRet[$aRet[0][0]][0] = ($i - $aRet[$aRet[0][0]][1] * $iWidth)
		$aRet[$aRet[0][0]][2] = Hex(PixelGetColor($aRet[$aRet[0][0]][0], $aRet[$aRet[0][0]][1]), 6)
	EndIf
Next
ReDim $aRet[$aRet[0][0] + 1][3]
_ArrayDisplay($aRet, $sColor)



Добавлено:
Сообщение автоматически объединено:

Еще можно заменить
Код:
;...
$iWidth = _GDIPlus_ImageGetWidth($hBitmap) - 1
$iHeight = _GDIPlus_ImageGetHeight($hBitmap) - 1
;...
на
Код:
;...
$aTemp = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
;If @error Or $aTemp[0] Then Exit  _GDIPlus_Shutdown()
$iWidth = $aTemp[2] - 1
$iHeight = $aTemp[3] - 1
;...
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
peter911
Можно попробовать сделать примерно как здесь:
http://autoit-script.ru/index.php?topic=11200.msg74202#msg74202

т.е. смасштабировать группу пикселей в один большой "пиксель".
Но там проще, т.к. в конечном итоге речь не о "среднем" цвете, а о средней яркости участка картинки.
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
Спасибо, всегда думал что регулярные выражения очень медленные

Нашел ошибку, при поиске FF0000 он находит например F0F0F0
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
64e97f0cc049.png

Слева область поиска, справа резльтат


Добавлено:
Сообщение автоматически объединено:

Я написал функцию, для мультипоиска цвета. Пожалуйста проверьте, я не могу понять работает или нет.

Код:
#include <Array.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>

$Timer = TimerInit()
$Arr = MultiPixel(0, 0, 50, 50)
ConsoleWrite(TimerDiff($Timer)/1000)
_ArrayDisplay($Arr)

Func MultiPixel($l, $t, $r, $b, $c="FFFFFF")
   Local $x=0, $y=0, $i=0, $j=0
   Local $Width = $r-$l, $Height = $b-$t
   Dim $Res[$Width*$Height][2]
   ;Dim $Res[1]
   _GDIPlus_Startup()
   $Data = Hex(DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData(_GDIPlus_BitmapLockBits(_GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture('', $l, $t, $r, $b)), 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB), 'Scan0')), 1), 6)
   _GDIPlus_Shutdown()
   $Width -= 1
   For $j=0 To StringLen($Data) Step 8
	  If $x >= $Width Then
		 $x = 0
		 $y += 1
		 ContinueLoop
	  EndIf
	  If StringMid($Data, $j, 6)==$c Then
		 $Res[$i][0] = $x
		 $Res[$i][1] = $y
		 ;$Res[$i][2] = Hex(PixelGetColor($x, $y), 6)
		 $i += 1
	  EndIf
	  $x += 1
   Next
   If $i < 1 Then
	  SetError(1)
	  Return False
   EndIf
   ReDim $Res[$i][2]
   Return $Res
EndFunc



Простите за
Код:
   $Data = Hex(
	  DllStructGetData(
		 DllStructCreate('byte[' & ($Width * $Height * 4) & ']',
			DllStructGetData(
			   _GDIPlus_BitmapLockBits(
				  _GDIPlus_BitmapCreateFromHBITMAP(
					 _ScreenCapture_Capture('', $l, $t, $r, $b)
				  ), 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB
			   ), 'Scan0'
			)
		 ), 1
	  ), 6
   )
В одну строчку.


Добавлено:
Сообщение автоматически объединено:

Я проверил, все работает за 0.03 сек. :IL_AutoIt_1:
Против 1 сек. на регулярках. и 30 минут на For GetPixel.



Добавлено:
Сообщение автоматически объединено:

Сделал функцию удаления соседних точек
Код:
Func toPoint(ByRef $Arr, $e=1)
   $i=1
   While $i < UBound($Arr)
	  For $j=0 To $i-1
		 If (Abs($Arr[$i][0]-$Arr[$j][0]) <= $e And Abs($Arr[$i][1]-$Arr[$j][1]) <= $e) Then
			_ArrayDelete($Arr, $j)
			$i -= 2
			ExitLoop
		 EndIf
	  Next
	  $i += 1
   WEnd
EndFunc


Например, у меня от 111 точек осталось только 11 "уникальных"
Использовать:
Код:
toPoint($Arr)

Второй параметр - точность. Алгоритм очень медленный из-за _ArrayDelete если например 10 тыс. точек сравнить надо. Поэтому нужен аналог.

Для поиска в клиенском моде можно использовать:
Код:
#include <WinAPI.au3>

$c = ClientArea()
MouseMove($c[0], $c[1])

Func ClientArea($Class = "[ACTIVE]")
   $Wnd = WinGetHandle($Class)
   Local $Point = DllStructCreate("int X;int Y")
    DllStructSetData($Point, "X", 00)
    DllStructSetData($Point, "Y", 0)
    _WinAPI_ClientToScreen($Wnd, $Point)
	Dim $Arr[2] = [DllStructGetData($Point, "X"), DllStructGetData($Point, "Y")]
	Return $Arr
EndFunc


Надеюсь кому поможет.

Окончательный вариант с расчетом длины. Чем меньше найдено пикселей этого цвета, тем быстрей.

Код:
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
Opt("PixelCoordMode", 2)
Opt("MouseCoordMode", 2)
Opt("CaretCoordMode", 2)
Sleep(3000)
$Timer = TimerInit()
Dim $Point[2] = [25, 25]
$A = PointSearch("FFFFFF", $Point, 0, 0, 100, 100)
If Not IsArray($A) Then
   l("Color", "not found!")
   Exit 0
EndIf
l("Timer", TimerDiff($Timer)/1000)
l("Lenght", Int($A[2]))
l("Coords", "x"&$A[0]&", y"&$A[1])
l("Color", "#"&Hex(PixelGetColor($A[0], $A[1]), 6))
MouseMove($A[0], $A[1])

Func l($k, $v)
   ConsoleWrite($k&": "&$v&@CRLF)
EndFunc

Func PointSearch($c, $p, $l, $t=0, $r=0, $b=0, $e=1)
   $Arr = MultiPixel($l, $t, $r, $b, $c)
   If $Arr == False Then Return False
   $Arr = toPoint($Arr, $e)
   If Not IsArray($Arr) Then Return False
   Dim $Coords[3] = [0, 0, 0]
   For $i=0 To UBound($Arr)-1
	  $Len = Sqrt(($Arr[$i][0]-$p[0])^2+($Arr[$i][1]-$p[1])^2)
	  If $Len < $Coords[2] Or $Coords[2] == 0 Then
		 $Coords[0] = $Arr[$i][0]
		 $Coords[1] = $Arr[$i][1]
		 $Coords[2] = $Len
	  EndIf
   Next
   Return $Coords
EndFunc

Func MultiPixel($l, $t, $r, $b, $c="FFFFFF")
   Local $x=0, $y=0, $i=0, $j=0
   If Opt("PixelCoordMode")<>1 Then
	  $ca = ClientArea()
	  $l += $ca[0]
	  $t += $ca[1]
	  $r += $ca[0]
	  $b += $ca[1]
   EndIf
   Local $Width = $r-$l, $Height = $b-$t
   Dim $Res[$Width*$Height][2]
   _GDIPlus_Startup()
   $Data = Hex(DllStructGetData(DllStructCreate('byte[' & ($Width * $Height * 4) & ']', DllStructGetData(_GDIPlus_BitmapLockBits(_GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture('', $l, $t, $r, $b)), 0, 0, $Width, $Height, $GDIP_ILMREAD, $GDIP_PXF32ARGB), 'Scan0')), 1), 6)
   _GDIPlus_Shutdown()
   $Width -= 1
   For $j=1 To StringLen($Data) Step 8
	  If $x >= $Width Then
		 $x = 0
		 $y += 1
		 ContinueLoop
	  EndIf
	  $s = StringMid($Data, $j, 6)
	  $s = StringMid($s, 5, 2)&StringMid($s, 3, 2)&StringMid($s, 1, 2)
	  If $s==$c Then
		 $Res[$i][0] = $x
		 $Res[$i][1] = $y
		 $i += 1
	  EndIf
	  $x += 1
   Next
   If $i < 1 Then
	  SetError(1)
	  Return False
   EndIf
   ReDim $Res[$i][2]
   Return $Res
EndFunc


Func toPoint(ByRef $Arr, $e=1)
   Local $k=0
   Dim $Res[UBound($Arr)][2]
   For $i=0 To UBound($Arr)-1
	  $n=$i
	  For $j=$i+1 To UBound($Arr)-1
		 If Not((Abs($Arr[$j][0]-$Arr[$n][0]) > $e Or Abs($Arr[$j][1]-$Arr[$n][1]) > $e)) Then $n = $j
	  Next
	  If $n == $i Then
		 $Res[$k][0] = $Arr[$n][0]
		 $Res[$k][1] = $Arr[$n][1]
		 $k += 1
	  EndIf
   Next
   ReDim $Res[$k][2]
   Return $Res
EndFunc


Func ClientArea($Class = "[ACTIVE]")
   $Wnd = WinGetHandle($Class)
   Local $Point = DllStructCreate("int X;int Y")
    DllStructSetData($Point, "X", 00)
    DllStructSetData($Point, "Y", 0)
    _WinAPI_ClientToScreen($Wnd, $Point)
    Dim $Arr[2] = [DllStructGetData($Point, "X"), DllStructGetData($Point, "Y")]
    Return $Arr
 EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
peter911 [?]
Я написал функцию, для мультипоиска цвета. Пожалуйста проверьте
Тоже столкнулся с проблемой быстрого поиска всех пикселей одного цвета. Ваша функция, действительно, самая быстрая из найденных мною на этом форуме. Но и самая неточная: в белом квадрате 10х10 находит 89 белых пикселей :(

Пришлось сочинять самому. За основу был взят пример http://autoit-script.ru/index.php?topic=3943.msg29329#msg29329 и вот что получилось
Код:
#include <Array.au3>
#include <WinAPIEx.au3>
#include <WindowsConstants.au3>

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

Func _PixelGetArray($iX, $iY, $iWidth, $iHeight, $iColor, $hWnd = 0)
	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
		EndIf
	Next
	ReDim $aPixels[$iCount + 1][2]
	$aPixels[0][0] = $iCount
	Return $aPixels
EndFunc   ;==>_PixelGetArray
При той же скорости ещё и возможность работы относительно клиентской области окна (по умолчанию относительно рабочего стола).
 
Верх