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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 10.06.2010, 13:59   #1
rokweb
Пользователь
 
Регистрация: 15.01.2010
Сообщений: 18
Восклицание Попиксельное сравнение двух битмапов.

Здравствуйте форумчане! Имеется задача - делать скрины экрана каждые 250 мс.(интервал между скринами тоже 250 мс). Эти скрины за 250 мс. нужно попиксельно сравнить и если есть отличие(пиксель отличается по цвету - навести на пиксель курсор мыши и сделать еще одну проверку: если иконка курсора изменилась, то зажать(!) лкм, зажать(!) пкм, отпустить отпустить лкм. ЛКМ и ПКМ - Левая и правая кнопки мыши соответственно. Собственно вот код, которые по непонятным мне причинам глючит и если и работает(такое бывает иногда =)) то очень нестабильно:
Код:

CONST
PixelCountMax = 32768;

type

pRGBArray = ^TRGBArray;
TRGBArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;

procedure TForm1.Timer1Timer(Sender: TObject);
var
 x,y: integer;
 P1, P2 : pRGBArray;
 DC: HDC;
 CurrentState: Cardinal;
 CI: TCursorInfo;
begin

If ScreenShot=False then
BitBlt(b1.Canvas.Handle, 0,0, Screen.Width, Screen.Height,DC, 0,0,SRCCOPY);

If ScreenShot=True then
begin

BitBlt(b2.Canvas.Handle, 0,0, Screen.Width, Screen.Height,DC, 0,0,SRCCOPY);

X:=0;
Y:=0;

b1.PixelFormat := PF24BIT;
b2.PixelFormat := PF24BIT;

  for Y := 0 to B1.Height-1 do
    begin
     P1:= pRGBArray(B1.ScanLine[y]);
     P2:= pRGBArray(B2.ScanLine[y]);
      for X := (B1.Width-1) DownTo 1  do
        begin
          If (P1[X].rgbtBlue<>P2[X].rgbtBlue) or (P1[X].rgbtGreen<>P2[X].rgbtGreen) or (P1[X].rgbtRed<>P2[X].rgbtRed)then
            Begin
              CI.cbSize := SizeOf(CI);
              GetCursorInfo(CI);
              If IntToStr(Image1.Picture.Icon.Handle) <> IntToStr(Ci.hCursor) then
                  Mouse.CursorPos := Point(X, Y)
                  Else Begin
                  mouse_event(MOUSEEVENTF_LEFTDOWN,X,Y,0,0);
                  Sleep(25);
                  mouse_event(MOUSEEVENTF_RIGHTDOWN,X,Y,0,0);
                  Sleep(25);
                  mouse_event(MOUSEEVENTF_RIGHTUP,X,Y,0,0);
                  Sleep(25);
                  mouse_event(MOUSEEVENTF_LEFTUP,X,Y,0,0);
                  ScreenShot:=False;
                  B1.FreeImage;
                  B2.FreeImage;
                  Exit;
                  End;
            End;
          Application.ProcessMessages;
            End;
      Application.ProcessMessages;
End;
End;
ScreenShot := Not ScreenShot;
End;
ReleaseDC( 0, DC );
end;
P.S. Из кода убрал лишнее - было довольно много обвесов, которые нужны в дальнейшем, чтобы понять суть проблемы, а она такова - курсор если и наводится на изменившийся пиксел то после этого курсор резко перепрыгивает на другой пиксель и начинает вообще прыгать по экрану.

P.P.S. Прошу заметить - скрины и управление мышкой нужно делать в чужом окне.
rokweb вне форума Ответить с цитированием
Старый 10.06.2010, 18:06   #2
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Сразу же замечу
Цитата:
Код:
 for X := (B1.Width-1) DownTo 1  do
Вы перебираете с шагом 1, а надо с шагом, зависящим от B1.PixelFormat
Sibedir вне форума Ответить с цитированием
Старый 10.06.2010, 18:28   #3
rokweb
Пользователь
 
Регистрация: 15.01.2010
Сообщений: 18
По умолчанию

При PF24BIT, надо с шагом 3? Как перебирать только определенную область экрана? Например область как на скриншоте:


P.S. За основу был взят код из статьи: http://forum.vingrad.ru/faq/topic-157023.html

P.P.S. Т.е. правильнее будет перебирать вот так? :
Код:
for Y := B1.Height-150 downto 150  do
begin
for X := (B1.Width-1) DownTo 0 div 3 do
begin
Это с областью перебора от B1.Height-150 строки пикселов до 150 строки пикселов с шагом строки 1 и с шагом прохода пикселов 3? Я правильно понял? Простите если выражаюсь не слишком понятно\корректно =)

Последний раз редактировалось rokweb; 10.06.2010 в 19:16.
rokweb вне форума Ответить с цитированием
Старый 10.06.2010, 19:51   #4
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

0 div 3 = 0

Отвечу более полно чуть позже
Sibedir вне форума Ответить с цитированием
Старый 10.06.2010, 20:21   #5
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Вот, кое что тут подсмотрел
http://delphiworld.narod.ru/base/use...emulation.html

Во вложении вроде то, что вам надо. С нажатием кнопок думаю сами дальше разберетесь. Но если что - спрашивайте.
Вложения
Тип файла: zip ScanScreen.zip (1.6 Кб, 39 просмотров)
Sibedir вне форума Ответить с цитированием
Старый 10.06.2010, 21:16   #6
rokweb
Пользователь
 
Регистрация: 15.01.2010
Сообщений: 18
По умолчанию

Огромное при огромное тебе спасибо, выручил очень меня! Теперь работает, буду дальше разбираться с нажатиями!
rokweb вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сравнение двух прайсов qwerty1 Microsoft Office Excel 10 15.01.2015 18:32
сравнение двух днф Zln Помощь студентам 0 11.05.2010 16:42
сравнение двух строк aza_kaz Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 3 01.01.2010 23:40
сравнение двух фаилов al508 Microsoft Office Excel 4 24.06.2009 07:55
попиксельное сравнение borodaj Общие вопросы Delphi 7 31.05.2007 13:24