Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.05.2015, 22:30   #1
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию Чтения пикселя сверху в низ

Как прочитать пиксели сверху в низ а не снизу вверх ??

Вот мой набросок

Код:
    y := Faft.Height - top;
    while y > 0 do
    begin
      for x := left to Faft.Width - 1 do
      begin
        col := Faft.GetPixel(Faft.Height-y, x);

      end;
      Dec(y);
    end;
Но он не совсем правильно работает((
Должно быть имя? вне форума Ответить с цитированием
Старый 18.05.2015, 01:43   #2
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию

Ладно, вот весь код, надеюсь поможете с этими циклами. Для работы нужна FastDIB

Суть кода, что бы он нашел нужный пиксель, аналог функции

Код:
function ScrWindows(Wnd: HWND; SrcDC: HDC; X, Y, Width, Height, XSrc,
  YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
Var
  DC: HDC;
begin
  Result := false;

  DC := GetDC(Wnd);
  if DC <> 0 then
  begin
    if BitBlt(SrcDC, X, Y, Width, Height, DC, XSrc, YSrc, Rop) then
      Result := true;
    ReleaseDC(Wnd, DC);
  end;
end;

function PixelSearch(out OutRes: TPoint; left, top, right, bottom,
  color: Integer; nVar: Byte = 0; ModeBGR: Boolean = true): Boolean;
var
  DC    : HDC;
  Faft  : TFastDIB;
  X, Y  : Integer;
  Col   : TFColor;
  red,      green,      blue      : Byte;
  red_low,  green_low,  blue_low  : Byte;
  red_high, green_high, blue_high : Byte;
begin
  Result := false;
  OutRes.X := 0;
  OutRes.Y := 0;

  if ModeBGR then
    color := (color and $FF0000) shr 16 or
             (color and $00FF00) or
             (color and $0000FF) shl 16;

  red   := GetRValue(color);
  green := GetGValue(color);
  blue  := GetBValue(color);

  if nVar > 0 then
  begin
    if nVar > red then red_low := 0 else red_low := red - nVar;
    if nVar > green then green_low := 0 else green_low := green - nVar;
    if nVar > blue then blue_low := 0 else blue_low := blue - nVar;
    if nVar > $FF - red then red_high := $FF else red_high := red + nVar;
    if nVar > $FF - green then green_high := $FF else green_high := green + nVar;
    if nVar > $FF - blue then blue_high := $FF else blue_high := blue + nVar;
  end
  else
  begin
    red_high    := red;
    red_low     := red_high;
    green_high  := green;
    green_low   := green_high;
    blue_high   := blue;
    blue_low    := blue_high;
  end;

  top   := abs(top);
  left  := abs(left);

  Faft := TFastDIB.Create(right, bottom, 24);
  if ScrWindows(0, Faft.HDC, 0, 0, Faft.Width, Faft.Height, left, top) then
  begin
    for Y := 0 to Faft.Height - 1 do
    begin
      for X := 0 to Faft.Width - 1 do
      begin
        Col := Faft.GetPixel(Y,  X);
        if (col.r >= red_low)   and (col.r <= red_high) and
           (col.g >= green_low) and (col.g <= green_high) and
           (col.b >= blue_low)  and (col.b <= blue_high) then
        begin
        ShowMessage( '1' );
          {OutRes.X := x + left;
          OutRes.Y := (Faft.Height - 1) - y;
          FreeAndNil(Faft);
          Result := true;
          exit;           }
        end;
      end;
    end;
    FreeAndNil(Faft);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Resilt: TPoint;
begin
  if PixelSearch(Resilt, 20,0, 563, 34, $FDE3DF) then
  begin
    ShowMessage(Resilt.X.ToString + '-' + Resilt.Y.ToString);
    SetCursorPos(Resilt.X, Resilt.Y);
  end;
end;
Должно быть имя? вне форума Ответить с цитированием
Старый 18.05.2015, 05:40   #3
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Код:
for i := сверху downto вниз do
не?
Или соответствующим образом переделать while.

А вообще, для работы нужен не просто фастдиб (если это фастлиб, о которой я думаю), а надо выложить весь проект архивом, вместе с фастдибом (в архиве pas файлы немного займут места), а также с нужными картинками, т.к. вдруг от них зависит (например, емнип, bmp имеет вариацию с перевёрнутым порядком пикселей, это по заголовку формата в файле надо выявлять), чтобы протестировать можно было сразу.
В код не вчитывался, и не вижу смысла, открою только под отладкой проект, не могу тратить время ещё и на сборку проекта до рабочего состояния.

Последний раз редактировалось phomm; 18.05.2015 в 05:54.
phomm вне форума Ответить с цитированием
Старый 18.05.2015, 07:36   #4
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Код:
for i := сверху downto вниз do
не?
Или соответствующим образом переделать while.

А вообще, для работы нужен не просто фастдиб (если это фастлиб, о которой я думаю), а надо выложить весь проект архивом, вместе с фастдибом (в архиве pas файлы немного займут места), а также с нужными картинками, т.к. вдруг от них зависит (например, емнип, bmp имеет вариацию с перевёрнутым порядком пикселей, это по заголовку формата в файле надо выявлять), чтобы протестировать можно было сразу.
В код не вчитывался, и не вижу смысла, открою только под отладкой проект, не могу тратить время ещё и на сборку проекта до рабочего состояния.
Цитата:
Или соответствующим образом переделать while.
Пробовал, результат 0

Цитата:
А вообще, для работы нужен не просто фастдиб
В обще просто фастдиб который качается по первой ссылке в гугле


Цитата:
В код не вчитывался, и не вижу смысла
Так я же написал, там тока надо правильно пикселя прочитать

Цитата:
а также с нужными картинками, т.к. вдруг от них зависит (например, емнип, bmp имеет вариацию с перевёрнутым порядком пикселей, это по заголовку формата в файле надо выявлять), чтобы протестировать можно было сразу.

Ну вот, вы же пишете что не видите смысл вчитываться в код, а тут пишете такое. Хотя в коде понятно что мы делаем скрин всего экрана, и грузим это дела в фастдиб. После чего надо найти нужный пиксель


---------

В Uses у меня тока прописана FastDIB(pus) что бы проект собрался

Последний раз редактировалось Должно быть имя?; 18.05.2015 в 07:41.
Должно быть имя? вне форума Ответить с цитированием
Старый 18.05.2015, 07:48   #5
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию

Вот аналог функции на c++ прям из AutoIt
Но я не понимаю, почему в их сборке GetPixel работает мгновенно, а при моей медленно!!!!!!!! УЖАССС...

Код:

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()
Должно быть имя? вне форума Ответить с цитированием
Старый 18.05.2015, 08:15   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Цитата:
Ну вот, вы же пишете что не видите смысл вчитываться в код, а тут пишете такое. Хотя в коде понятно что мы делаем скрин всего экрана, и грузим это дела в фастдиб. После чего надо найти нужный пиксель
Код я видел, прочитал по диагонали и понял, что там делается в целом, я не вчитывался в операции над пискелями.
Стало быть, Вы предлагаете на _моём_ скрине найти нужный _Вам_ пиксель ? Ну, удачи, чо.
Это типа намёк Вам адаптировать проект для "потенциального помогающего", в том числе запилить чтение картинки из файла, который Вы у себя сохраните и приложите. Да и создавать проект из кусков кода, заливать и подключать либы и возможно что-то ещё адаптировать (например, Вы юзаете ToString, мне у себя [дельфи2007] либо этот кусок выкидывать либо заменять на инттустр, ну это я чисто как пример, что надо потрудиться для того, чтобы просто приступить к отладке, а Вы не хотите этому поспособствовать, хотя надо-то Вам).
phomm вне форума Ответить с цитированием
Старый 18.05.2015, 08:28   #7
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Код я видел, прочитал по диагонали и понял, что там делается в целом, я не вчитывался в операции над пискелями.
Стало быть, Вы предлагаете на _моём_ скрине найти нужный _Вам_ пиксель ? Ну, удачи, чо.
Это типа намёк Вам адаптировать проект для "потенциального помогающего", в том числе запилить чтение картинки из файла, который Вы у себя сохраните и приложите. Да и создавать проект из кусков кода, заливать и подключать либы и возможно что-то ещё адаптировать (например, Вы юзаете ToString, мне у себя [дельфи2007] либо этот кусок выкидывать либо заменять на инттустр, ну это я чисто как пример, что надо потрудиться для того, чтобы просто приступить к отладке, а Вы не хотите этому поспособствовать, хотя надо-то Вам).
Вы не поняли.
Я не предлагаю искать определенный пиксель который я указал! "$FDE3DF"
Вы его можете поменять на свой! я его лично нашел через программу Au3Info.exe


По вашему мнению, пример по этой ссылке, тоже желает большой удачи в поисках ....
Код:
; Найти чисто красный пиксель в прямоугольнике 0,0-20,300
$coord = PixelSearch(0, 0, 20, 300, 0xFF0000)
If Not @error Then
    MsgBox(0, "X и Y равны:", $coord[0] & "," & $coord[1])
EndIf

; Найти чисто красный пиксель или пиксель с отклонением 10 градаций от чисто красного
$coord = PixelSearch(0, 0, 20, 300, 0xFF0000, 10)
If Not @error Then
    MsgBox(0, "X и Y равны:", $coord[0] & "," & $coord[1])
EndIf


И тут вряд ли отладка нужна, код не каких исключений не выкидывает!! я и пишу, пиксели нужна в правильном порядке прочитать
Должно быть имя? вне форума Ответить с цитированием
Старый 18.05.2015, 09:13   #8
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Цитата:
Сообщение от Должно быть имя? Посмотреть сообщение
Цитата:
Код:
for i := сверху downto вниз do
не?
Или соответствующим образом переделать while.
Пробовал, результат 0
Как пробовали ?
Код:
for Y := Faft.Height - 1 downto 0 do
так ? Это поправленная строка из поста #2
Примечание - цикл по Х надо оставить как есть.

В остальном, Вы не хотите меня услышать, что ж, возможно, попробую потестить код, если время будет.

BTW, для справки, отладка бывает не только ошибок работы программы как кода, а ещё и отладка алгоритма, т.е. мат. модели.

Последний раз редактировалось phomm; 18.05.2015 в 09:16.
phomm вне форума Ответить с цитированием
Старый 18.05.2015, 09:30   #9
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Как пробовали ?
Код:
for Y := Faft.Height - 1 downto 0 do
так ? Это поправленная строка из поста #2
Примечание - цикл по Х надо оставить как есть.

В остальном, Вы не хотите меня услышать, что ж, возможно, попробую потестить код, если время будет.

BTW, для справки, отладка бывает не только ошибок работы программы как кода, а ещё и отладка алгоритма, т.е. мат. модели.
Проблема оказалась в другом

По координатам x - 1158 y - 753 есть цвет FAFBFD.
Именно со сделанного bmp скриншота
А visual studio видит его как FFFAFBFD в RGBA

Код:

  Faft := TFastDIB.Create(right, bottom, 24);
  if ScrWindows(0, Faft.HDC, 0, 0, Faft.Width, Faft.Height, left, top) then
  begin
    Faft.SaveToFile('1.bmp'); // сохраняет скриншот

    Col := Faft.Pixels[753, 1158]; // пробуем получить цвет
    ShowMessage( Col.b.ToString + ':' + col.g.ToString +':'  + col.r.ToString());
    FreeAndNil(Faft);
  end;

И в сообщение вылазит 0:0:0

Почему так происходит??
Должно быть имя? вне форума Ответить с цитированием
Старый 18.05.2015, 11:32   #10
Должно быть имя?
Пользователь
 
Регистрация: 11.04.2015
Сообщений: 68
По умолчанию

Чуть посидел, намутил tagRGBTRIPLE со ScanLine
Дальше якобы^^ получаю RGB который не херашеньки не RGB А BGR перевожу его, и получаю с картинки одинаковый цвет ))

Код:
        TestColor := rgb(p^[x].rgbtRed, p^[x].rgbtGreen, p^[x].rgbtBlue);
        BGRtoRGB(TestColor);

        red		:= GetRValue(TestColor);
        green	:= GetGValue(TestColor);
        blue	:= GetBValue(TestColor);


ShowMessage('Red: ' + IntToStr(red) + ' Green: ' + IntToStr(green) + ' Blue : ' + IntToStr(blue) + #10#13 +
          'Red: ' + IntToStr(red_high) + ' Green: ' + IntToStr(green_high) + ' Blue : ' + IntToStr(blue_high));
Должно быть имя? вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Алгоритм программного чтения кода(наподобие чтения тегов в браузерах) psih_stalker Gamedev - cоздание игр: Unity, OpenGL, DirectX 3 10.01.2012 21:32
Опустить web browser в самый низ matvey.tech C# (си шарп) 0 10.01.2012 01:36
Верх и низ имаги в CSS Alex Cones HTML и CSS 7 23.10.2010 18:00
Прижать левый блок максимально в низ. rext HTML и CSS 6 17.07.2010 13:50
функции чтения цвета пикселя Геннадий Общие вопросы Delphi 1 13.11.2006 20:03