Ako porovnam 2 BItmapy? – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Ako porovnam 2 BItmapy? – Delphi – Fórum – Programujte.comAko porovnam 2 BItmapy? – Delphi – Fórum – Programujte.com

 

Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
15. 1. 2010   #1
-
0
-

Mozete mi prosim poradit ako mam porovnat dve bitmapy? aby bol vysledok true alebo false..
Skusal som if Bitmap1 <> Bitmap2 then ..... zrejme je to blbost ja viem necudo ze to nefunguje .. co by som v tom asi mal porovnavat? pls....

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
15. 1. 2010   #2
-
0
-

musis pekne bajt po bajtu..

Nahlásit jako SPAM
IP: 80.250.1.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
15. 1. 2010   #3
-
0
-

To KIIV :
s pracou s binarnymi datami moc nemam skusenosti.. mozes mi napisat akoby som to mal urobit? popripade aj nejaku ukazku ..

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
15. 1. 2010   #4
-
0
-

To Patrik Skoupý : mel by tam byt zpusob jak ziskat ukazatel na cely radek nebo podobne.. pripadne na cele pole pixelu..

Nahlásit jako SPAM
IP: 80.250.1.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #5
-
0
-

To KIIV :
na nete som nasiel len toto.... problem je ze tomu moc nerozumiem.. no programovaniu sa venujem vaznejsie len asi tak 4 - 5 mesiacov.. cize mam iste medzery ... nejaky jednoduchsi sposob by nebol?

procedure CalcBitmapCRC32(Bitmap: TBitmap; lCRC: PlArrayCRC);
var i, j, k, l, lSquareHeight, lSquareWidth: Cardinal;
Lines: Array[0..lSquare-1]of Pointer;
begin
if (Bitmap.Height<=0) or (Bitmap.Width<=0) then Exit;
if ((Bitmap.Height mod lSquare)>0) or ((Bitmap.Width mod lSquare)>0) then
Exit;
lSquareHeight:=Bitmap.Height div lSquare;
lSquareWidth:=Bitmap.Width div lSquare;
for i:=0 to (lSquareHeight-1) do // 1 průběh pro každý řádek čtverců.
begin
for j:=0 to (lSquare-1) do
Lines[j]:=Bitmap.ScanLine[i*lSquare+j];
for j:=0 to (lSquareWidth-1) do // 1 průběh pro každý čtverec v 1 řádku.
begin
lCRC^[j,i]:=$FFFFFFFF;
for k:=0 to (lSquare-1) do // 1 průběh pro každý blok dat = 1 řádek
// v 1 čtverci.
for l:=0 to (lSquare-1) do // 1 průběh pro každý pixel v 1 řádku
// 1 čtverce.
lCRC^[j,i]:=UpdateCrc32(Byte(Pointer(
Cardinal(Lines[k])+j*lSquare+l)^),lCRC^[j,i]);
lCRC^[j,i]:=not lCRC^[j,i];
end;
end;
end;

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #6
-
0
-

vicemene z toho vidis kde bere jednotlivy pixely.. scanline..

Nahlásit jako SPAM
IP: 80.250.1.–
Program vždy dělá to co naprogramujete, ne to co chcete...
liborb
~ Redaktor
+18
Guru
16. 1. 2010   #7
-
0
-

A jestli to máš na ty přenášené screenshoty, tak můžeš ušetřit nějaký čas tím, že nebudeš porovnávat všechny řádky, ale např. jenom každý 8. a stejně tak nemusíš porovnávat všechny barvy, ale můžeš to testovat co 4. bajt.
Nebo můžeš dělat z řádků něco jako kontrolní součet, možná by to bylo rychlejší.
Pokud ovšem chceš naprosto přesný výsledek, tak musíš porovnat všechny bajty.

Nahlásit jako SPAM
IP: 91.203.96.–
liborb
~ Redaktor
+18
Guru
16. 1. 2010   #8
-
0
-

A jestli to máš na ty přenášené screenshoty, tak můžeš ušetřit nějaký čas tím, že nebudeš porovnávat všechny řádky, ale např. jenom každý 8. a stejně tak nemusíš porovnávat všechny barvy, ale můžeš to testovat co 4. bajt.
Nebo můžeš dělat z řádků něco jako kontrolní součet, možná by to bylo rychlejší.
Pokud ovšem chceš naprosto přesný výsledek, tak musíš porovnat všechny bajty.

Nahlásit jako SPAM
IP: 91.203.96.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #9
-
0
-

To KIIV :
no jo ale tomu algoritmu moc nerozumiem.. napr co je to LSquare alebo ICRC.. no a nebolo by jednoduchsie porovnavat 2 jpg obrazky?? ide tu o to ze robim screeny obrazovky a posielam do aplikacie druheho pocitaca.. cize najprv urobim bitmapu potom z toho jpg a potom to hodim do memorystreamu a preposlem .. aked sa obrazovka nememi aby som neposielal zbytocne screeny.. alebo ako casto sa meni handle obrazovky? (funkcia GetWindowDC(GetDesktopWindow)) to handle sa zmeni len vtedy ak sa nieco na obrazovke prekresli? alebo je handle ine vzdy ked tu funkciu zavolam .. napadlo ma ze by som porovnaval to handle a tak zistil ci mam znovu poslat novy screen alebo ci nie..

Nahlásit jako SPAM
IP: 95.102.83.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #10
-
0
-

k tomu jpg.. provonavam ich velkost... vzdy je ina ak sa obrazok zmeni ale k tomu potrebujem ten obrazok dostat do nejakeho streamu a to hlavne nechcem robit..

Nahlásit jako SPAM
IP: 95.102.83.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #11
-
0
-

ok zistil som ze to handle mam furt rovnake (65556) cize asi zla moznost.. este ma napadlo .. ze trebars odchytavat nejake spravy ktore by prekreslovali okna a podla toho zistil ci mam poslat dalsi screen.. len k tomu neviem ako odchytavat spravy inych aplikacii a aku spravu bych mal asi odchytavat.. zacina sa mi to zbytocne komplikovat.. asi sa na to vybodnem

Nahlásit jako SPAM
IP: 95.102.83.–
Míša
~ Anonymní uživatel
106 příspěvků
16. 1. 2010   #12
-
0
-

Nestačil by třeba porovnat výsledek nějaké hashovací funkce použité na oba obrázky?

Nahlásit jako SPAM
IP: 88.102.27.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #13
-
0
-

To Míša :
Keby to bolo tak jednoduche plakal bych od radosti. :D

Nahlásit jako SPAM
IP: 95.102.83.–
liborb
~ Redaktor
+18
Guru
16. 1. 2010   #14
-
0
-

Ale ono to je jednoduché. Chceš použít hash, tak ho použij. Nedostaneš k celému obrázku najednou? Tak porovnávej hash jednotlivých řádků a můžeš i některé přeskočit, jak jsem psal výše. Výšku a šířku obrázku znáš, počet bajtů na pixel taky, takže spraví jeden for cyklus.

Nahlásit jako SPAM
IP: 91.203.96.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #15
-
0
-

k celemu obrazku naraz sa dostanem.. .. a co je to ten hash? ja nemam ani v najmensom ponatia co to je.. :D ako by som ho mal pouzit? mozte mi napisat nejaku jednoduchu ukazku v kode?

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #16
-
0
-

To Patrik Skoupý [: kdyby tak existovalo neco, kam zadam neco, co hledam, a ono to naslo co to je... nj jenze nic takoveho proste neni...


btw: hash je shodou okolnosti napriklad to CRC32, MD5, ..... a spooooousty dalsich..
idealni hash je stejny jen pro stejne soubory (data), ze kterych je vytvoren.. realne je pak kvalita hashe umerna mnozstvi kolizi.. (ruzne soubory, ktere maji stejny hash)
a ano.. z hashe se neda ziskat puvodni soubor (data)

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #17
-
0
-

To KIIV :
a nieje v delphi nejaka uz zabudovana funkcia hashu? trebars ze tam hodim tu bitmapu a vypluje nejake cislo alebo nejaky kod alebo nieco tak ak som tomu teda spravne pochopil.. pretoze nechcem tam vkladat dlhy kod tej funkcie trebars co je vyssie napisana ked jej nerozumiem..

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #18
-
0
-

primo v delphi asi nebude.. ale kdyz uz mas tu cos sem hodil.. dokonce primo na cely obrazek... proc nevyuzit

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #19
-
0
-

To KIIV :
no na to aby som tomu algoritmu rozumel zrejme este niesom dostatocne daleko v znalosti delphi.. a ako som vravel nerad by som daval do svojho programu kody ktore neviem ako pracuju.. mimochodom .. skusal som porovnanie bitmap tak ze som porovnaval farbu jednotlivych pixelov...(canvas.pix[x,y]) ale pri obrazku 100x100 a volani tej funkcie asi 20 x za sekundu mi to procesor vytazovalo na 43 percent a .. je tu fakt ze pri porovnavani obrazkov z fullscreenu co je dost vysoke rozlisenie optimalnu hodnotu vytazenia procesoru by som mal mozno len vtedy tebz som porovnaval kazdy 100 pixel a to uz by bola docela blbost robit.. to uz je fakt realnejsie nacitat to jpg do streamu a potom len porovnat velkost (stream.size) ..

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #20
-
0
-

canvas je neskutecne pomalej.. pouzij scanline.. jak je v tom tvym kodu ..

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #21
-
0
-

To KIIV :
inak ak chcem porovnavat trebars kazdy 4 bajt v tom pointri scanline ako mam trebars do premenej typu byte dostat stvrty bajt z pointru? viem ze ak chcem dostat prvy tak pouzijem nieco take ze ziskanybajt:=byte(pointer^); ale ako ziskat dalsie? trebars stvrty osmy , dvanasty atd atd... este ma v tomto trosku nakopnite pls..

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #22
-
0
-

To Patrik Skoupý : nevim ted jestli to funguje jako v C .. (pointer+4)^ (resp v C jde i pointer[index])

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #23
-
0
-

skusal som ale nefunguje to, v delphi je to zrejme nejak inak..

Nahlásit jako SPAM
IP: 95.102.83.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #24
-
0
-

To KIIV :
skusal som ale nefunguje to, v delphi je to zrejme nejak inak.

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #25
-
0
-

podle google by melo jit aspon neco jako pointer := pointer + 4 ; pointer^ ... ; ale tezko rict

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #26
-
0
-

To KIIV : to mi taktiez nefunguje...

Nahlásit jako SPAM
IP: 95.102.83.–
KIIV
~ Moderátor
+43
God of flame
16. 1. 2010   #27
-
0
-
Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #28
-
0
-

To KIIV : no skusal som ale nefunguje mi to na premennu typu pointer.. iba na tie co mam typu byte alebo proste typovy nejakz pointer.... zrejme by fungovalo nieco ako ked zadefinujem PByte:^Byte; a potom kod bude takyto PByte:=Pointer; inc(PByte); potom by som vlastne precital z PByte druhy bajt Pointeru.. ale tak ta funkcia inc by tam musela byt dost vela krat aby som proste presiel cely obrazok tak ze budem porovnavat kaydy 4 popripade 8 bajt... potom bych tam tu funkciu musel davat 8x v nejakom cikle a tiez by mi procesor pritom nejasal radostou . :D

Nahlásit jako SPAM
IP: 95.102.83.–
TooM70
Newbie
16. 1. 2010   #29
-
0
-

To Patrik Skoupý : inc(PByte, 4)

Nahlásit jako SPAM
IP: 147.229.201.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
16. 1. 2010   #30
-
0
-

To TooM7 : aaaa funguje.. vdaka..

Nahlásit jako SPAM
IP: 95.102.83.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
17. 1. 2010   #31
-
0
-

To Patrik Skoupý :
no vytvoril som takuto porovnavaciu funkciu

function tform1.porovnaj(var bitm1,bitm2:TBitmap):boolean;
var i,j:integer;
bt1,bt2:^byte;
begin
result:=true;
for j:=1 to (r.Bottom div 8)-1 do
begin
bt1:=bitm1.ScanLine[j*8];
bt2:=bitm2.ScanLine[j*8];

for i:=1 to (r.Right div 2) do
begin
inc(bt1,8);
inc(bt2,8);
if bt1^ <> bt2^ then result:=false;
end;
end;
end;

no a nastal dalsi problem.. tuto funkciu vyvolavam asi tak 20 x za sec .. a pri asi prvom vyvolani mi procesor vystupi na otrasnych 46 percent na niekolko sekund asi 10 potom klesne na asi 12 percent.. no v hentom pripade je skenovany kazdy osmy riadok a v tom riadku kazdy ôsmy Byte.. nuz ide o to ze ak tie atributy zmenim trebars tak ze bude skenovany len kazdy druhy riadok ..pricom sa pocet porovnavani zostvornasobi ale . vytazenost procesora je furt okolo 12 percent... iba v provom volani tejto funkcie ked je nejako 46 percent tak netrva 10 sec ale dlhsie .. v com je problem?

Nahlásit jako SPAM
IP: 95.102.83.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
17. 1. 2010   #32
-
0
-

no a mimochodom ak funkciu volam asi tak 10 x za sec ..co je o polovicu menej krat.. tak sa aj vytazenost procesora znizi na 6 percent.. co je vlastne pochopitelne... .. ale nic ine v tom programe mi procesor nezere pretoze ak som funkciu odfiltroval tak program zral 0% proc... (podotikam ze program je novy skusobny nejedna sa o povodny program ktory mam na prenos screenshotov) pripada mi to celkom divne ..

Nahlásit jako SPAM
IP: 95.102.83.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
17. 1. 2010   #33
-
0
-

kod som trosku pozmenil ale ziadna zmena furt..

function tform1.porovnaj(var bitm1,bitm2:TBitmap):boolean;
var i,j:integer;
bt1,bt2:^byte;
begin
result:=false;
for j:=1 to (r.Bottom div 8)-1 do
begin
bt1:=bitm1.ScanLine[j*8];
bt2:=bitm2.ScanLine[j*8];

for i:=1 to (r.Right div 2) do
begin
inc(bt1,8);
inc(bt2,8);
if bt1^ <> bt2^ then exit;
end;
end;
result:=true;
end;

Nahlásit jako SPAM
IP: 95.102.83.–
liborb
~ Redaktor
+18
Guru
18. 1. 2010   #34
-
0
-

Řekl bych, že je to podobný problém jako u to převodu do/z JPG. Prostě těch dat je hodně na to, aby to nebralo strojový čas. Můžeš klidně vynechat více řádek (co se stane na 4, 8, 16, 32 pixlech?) podle toho, jak přesně chceš detekovat změnu. Je potřeba si uvědomit, že změna polohy okna apod. se ti projeví i při delším "vzorkování". Kdyby si detekoval každý 32. řádek a každý 32. pixel, tak nezjistíš pouze pohybu uvnitř těchto čtverců. Ale je vůbec reálné, aby ti to někdo zkoušel tak malými okny? :smile1: Leda tak kurzor, ale ten asi posíláš stejně extra, ne? A další možností, jak to trochu vylepšit, je netestovat to pravoúhlou mřížkou, ale buď náhodně nebo kosodelníky.

Druhá věc ovšem je, jestli na takové věci je vhodně Delphi. Určitě je to nástroj, ve které uděláš danou věc rychle. Ale neřekl bych (po zkušenostech s Borland produkty), že to i rychle poběží.

Nahlásit jako SPAM
IP: 85.207.166.–
Patrik Skoupý
~ Anonymní uživatel
23 příspěvků
18. 1. 2010   #35
-
0
-

To liborb :
ja porovnavam kazdy osmy bajt to znamena kazdy druhy pixel ale vnom iba jeden bajt.. a kazdy osmy riadok ale ak to zmenim trebars tak ze bude porovnavat 2x viac bajtob alebo 2x menej bajtov vytazenost procesora je furt rovnaka.. a aj sa mi meni aktivne velkost ukladanej bitmapy ale v tom to neni.. problem je v tom ze staci raz vyvolat pri novej bitmape funkciu scanline a vtedy ta vytazenost stupne.. potom uz nezalezi na tom kolko krat tu funkciu volam... procesor uz mi to nezere.. az ked bitmapu zmenim (novy screenshot) a znovu vyvolam funkciu scanline... keby som mal proceduru ktoru vyvolavam 20x za sekundu a bola by v nej iba nova bitmapa a 1x funkcia scanline vytazovalo by mi to procesor tak isto ako teras..

a ktej druhej veci.. Delphi je asi jedina vec v ktorej viem robit.. pretoze je tam jazyk pascal.. ja pouzivam delphi 7 ale teras som si neni isty ci delphi 2009 je produktom borland.. ten som mal tiez ale vobec som to nepouzival ... delphi 7 je o dost prehladnejsi.

Nahlásit jako SPAM
IP: 95.102.83.–
illioner0
Stálý člen
18. 1. 2010   #36
-
0
-

Zkus kdyžtak funkci GETDIBITS místo toho volání scanline obejde to Delphi, je to přímo win api.

nějak takhle:

GetDIBits( parametry:
handle of device context,
handle of bitmap ,
first scan line to set in destination bitmap ,
number of scan lines to copy ,
ukazatel - address of array for bitmap bits ,
address of structure with bitmap data (bi:BITMAPINFO),
RGB or palette index (napr. dib_rgb_colors)
);

var bi:BITMAPINFOHEADER;
bi.biSize := sizeof(BITMAPINFOHEADER);
bi.biWidth := SplashInfo.bmWidth;
bi.biHeight := SplashInfo.bmHeight;
bi.biPlanes := 1;
bi.biBitCount := 24;
bi.biCompression := BI_RGB;

Nahlásit jako SPAM
IP: 85.71.152.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
liborb
~ Redaktor
+18
Guru
18. 1. 2010   #37
-
0
-

To Patrik Skoupý : Nechtěl jsem ti Delphi rozmlouvat nebo tak něco. Jenom jsem chtěl říct, že jsi "zajatcem" postupů, které vymyslel někdo jiný. To je samozřejmě u všech knihoven, ale u Borlandu mi často přišlo, že zrovna ten jejich postup je skoro ten nejhorší (nebo jinak - málokdy mi přišel vhodný pro moje účely). A toto je podobná situace. Ty se divíš, že ti to při prvním volání scanline bere strojový čas a při dalších už ne. To bude nejspíš způsobené tím, že se při prvním volání natahuje do paměti celá bitmapa a při těch dalších už se data jenom prochází. A to je to, co se ti nehodí. Jednak nepotřebuješ všechna data a taky je nepotřebuješ najednou. Takže pokud se s tím nechceš smířit, tak to budeš muset obejít např. přes výše zmiňovanou funkci GetDIBits. Její volání pro jednotlivé řádky ti bude vytěžovat procesor rovnoměrně :-).

Nahlásit jako SPAM
IP: 91.203.96.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 10 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý