Jak porównać dwie bitmapy
Coldpeer
function GetDifference(Img1, Img2:TImage; var XStart, XStop, YStart, YStrop:integer):boolean;
var
Pixel1:^TrgbTriple;
Pixel2:^TrgbTriple;
x, y:integer;
TheSame:boolean;
begin
Img1.Picture.Bitmap.PixelFormat:=pf24bit;
Img2.Picture.Bitmap.PixelFormat:=pf24bit;
TheSame:=true;
for y:=0 to Img1.Picture.Bitmap.Height -1 do
begin
Pixel1:=Img1.Picture.Bitmap.ScanLine[y];
Pixel2:=Img2.Picture.Bitmap.ScanLine[y];
for x:=0 to Img1.Picture.Bitmap.Width-1 do
begin
if (Pixel1.RgbtRed<>Pixel2.RgbtRed) or
(Pixel1.RgbtGreen<>Pixel2.RgbtGreen)or
(Pixel1.RgbtBlue<>Pixel2.RgbtBlue) then
begin
if TheSame or (XStart>X) then XStart:=X;
if TheSame or (XStop<X) then XStop:=X ;
if TheSame or (YStart>Y) then YStart:=Y;
if TheSame or (YStrop<Y) then YStrop:=Y;
TheSame:=false;
end;
inc(Pixel1);
inc(Pixel2);
end;
Result:=not TheSame;
end;
end;
Kod pochodzi autorstwa Piotrkadp, pochodzący z tego wątku na forum. I jeszcze wersja dla C++Builder przetłumaczona przez AklimX-a:
bool GetDifference(TImage Img1, TImage Img2, int &XStart, int &XStop, int &YStart, int &YStrop)
{
TrgbTriple* Pixel1, *Pixel2;
int x, y;
bool TheSame;
Img1->Picture->Bitmap->PixelFormat = pf24bit;
Img2->Picture->Bitmap->PixelFormat = pf24bit;
TheSame = true;
for(y=0; y<Img1->Picture->Bitmap->Height; ++y)
{
Pixel1 =Img1->Picture->Bitmap->ScanLine[y];
Pixel2 =Img2->Picture->Bitmap->ScanLine[y];
for( x=0; x<Img1->Picture->Bitmap->Width; ++x)
{
if( (Pixel1->RgbtRed!=Pixel2->RgbtRed) ||
(Pixel1->gbtGreen!=Pixel2->RgbtGreen)||
(Pixel1->RgbtBlue!=Pixel2->RgbtBlue) )
{
if ((TheSame) || (XStart>X)) XStart=X;
if ((TheSame) || (XStop <X)) XStop =X;
if ((TheSame) || (YStart>Y)) YStart=Y;
if ((TheSame) || (YStrop<Y)) YStrop=Y;
TheSame=false;
}
++Pixel1;
++Pixel2;
}
}
return !TheSame;
}
Jesem kompletnym laikiem jeśli chodzi mi o programowanie. Potrzebny jest mi jednak program wykrywający zmiany na monitorze (np. odświeżenie i zmiana zawartości strony www). Nie wiem jak to zrobić- możnaby się pokusić (o ile nie ma prostszego rozwiązania) tworzenie co pewien czas screenów, i późniejsze porównywanie ich jako bitmapy (ale niestety nawet nie umiem wykorzystać podanego kodu). Prosiłbym o szczegółową pomoc. Z góry dziękuję
Jesem kompletnym laikiem jeśli chodzi mi o programowanie. Potrzebny jest mi jednak program wykrywający zmiany na monitorze (np. odświeżenie i zmiana zawartości strony www). Nie wiem jak to zrobić- możnaby się pokusić (o ile nie ma prostszego rozwiązania) tworzenie co pewien czas screenów, i późniejsze porównywanie ich jako bitmapy (ale niestety nawet nie umiem wykorzystać podanego kodu). Prosiłbym o szczegółową pomoc. Z góry dziękuję
Przyznam, że dziwi mnie to. Przecież porównanie czy zwiększanie (adresów) trwa tyle samo dla danych 1 i 4 bajtowych, a w drugim jest po prostu więcej operacji.. Na pierwszy rzut oka - bez sensu.
napisałem procedury tak :
Właczyłem test na wykonanie 10 000 razy na Bitmapie o wymiarach
500 X 500 pixeli no i procedura 2 z or ' ami okazała się szybsza za każdym razem o jakieś 1,7 sekundy
test przeprowadzany 20 krotnie na
Komputerze
AMD Athlon(tm) XP 1800+
1.50 GHz, 256 MB RAM System 32 bitowy
Do postu Szczawik'a: też mnie to zdziwiło ale być może czytając jako DWORD procesor porównuje wszystkie 3 bajty natomiast w or'owych wyskakuje dalej zaraz po pierwszym bajcie niezgodnym i może stąd ta roznica ale to tylko być może :) nie wiem nie znam się , nie orientuje się :)
Po pierwsze ustawienie 32bit pozwoliłoby na wykonanie jednego porównania na DWORD zamiast trzech z'or'owanych porównań na byte (po to w ogóle stworzono bmp 32bit, zanim jeszcze wprowadzono kanał alpha). Trzeba jednak pamiętać, że w tym wszystkim najbardziej czasochłonną operacją nie jest znalezienie różnic, ale zmiana głębi kolorów. Gdy bitmapy są już w głębi docelowej, wtedy można porównywać szybkość.
Pod drugie, skoro znamy kolejność przechodzenia w osi Y (tu rosnąco), to przy wykryciu różnicy nie trzeba sprawdzać, czy (StopY<Y), bo zawsze jest co najwyżej równe.
Przy odliczaniu pętlą w dół po obu osiach i skracając operacje w pętli mamy większe szanse na objęcie kodu przez cache procesora, a zatem być może nawet większy zysk szybkości.