» Poradna » Ostatní

Delphi. porovnani shodnosti dvou obazku v image

 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Zdravím,neumím si zjistit, zda jsou obbrazky v komponentách Image1 a 2 stejne. Myslel jsem, že to půjde lehce, ale zatím sem na nic nepřišel.A překvapivě ani na internetu se tomu nikdo nevěnuje v návodech.Co jsem zkusil a nefungujeif form1.Image1.Picture.Bitmap=form1.Image3.Picture.Bitmap then ShowMessage('stejne');if form1.Image1.Picture=form1.Image3.Picture then ShowMessage('stejne');

Mohlo by vás také zajímat

Odpovědi na otázku

 | Microsoft Windows 8 Opera 9.80

Tohle porovnava ukazatele na 2 ruzne objekty. Takze to fungovat ani nemuze.Pokud chces porovnat obrazky rychle, pouzij CompareMem()

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Díky za rychlou odpověď. Neporadil byste mi, ještě, jak se s tím kompare pracuje. Pravděpodobně to bude porovnávat bloky dat v paměti, ale s tím ja neumím pracovat.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

tak sem trochu ještě zkoušel a zkoumal. Už sem si jistej, že to porovnava dva bloky pameti. ja zada zacatek bloku a jeho delku. Ale nevim kde to mam v pameti ulozene. Neumim se k tomu dostat. Zkousel jsem toto a nic.if comparemem( form1.Image1.Picture.Bitmap.Canvas, //bud toto neni ukazatel do pametiform1.Image3.Picture.Bitmap.Canvas,form1.Image3.Picture.Bitmap.Canvas.InstanceSize //nebo toto neukazuje delku bloku) then ShowMessage('stejne'); Nevim, jsem bezradny. Potrebuju snimat čast obrazovky a až se tam neco objevi tak reagovat. Obrazovku uz si fotim. obrazky mam v image ale porovnat je neumim. Asi to budu muset dělat pixel po pixelu pres for to umim, ale bojim se že to bude pomalé a nestihnu 50 kontrol za sekundu.I kdyz kontroluju jen malou oblast. Zkuste mi někdo poradit jak to vyřešit.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Canvas je objekt třídy TCanvas. Tím se k datům bitmapy nedostaneš. Zkus si něco nastudovat o funkcí např. GetBitmapBits, ale to je trochu složitější. Je to API funkce.https://msdn.microsoft.com/en-us/library/windows/des... (v=vs.85).aspxNo a hlavně ti to porovnává surová data v paměti bajt po batju. VŠECHNY bajty se musí rovnat. Když ale porovnáváš dva obrázky...mohou se lišit, a přesto mohou být stejné (velmi mírně rozdílný úhel při focení, pokud vznikly převodem z JPG do BMP...nebo pokud rovnou "nahráváš" do TImage nějaké JPGy...budou se bitově lišit díky komprimaci, přesto budou totožné, mohou mít rozdílné rozlišení atd. Tohle fakt nejde porovnávat pouhým CompareMem.)

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Aha, jsem to nedočetl do konce. Pak by ti mělo stačit to GetBitmapBits.Jinak ani form1.Image1.Picture.Bitmap.Canvas není ukazatel to paměti, kde jsou data bitmapy a ani form1.Image3.Picture.Bitmap.Canvas.InstanceSize není velikost, která data bitmapy zabírají. Je to jen velikost kódu, co zabírá objekt Canvas.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Nebo kdybys to chtěl opravdu rychlé, takCreateBitmaphttps://msdn.microsoft.com/en-us/library/windows/des... (v=vs.85).aspxpříp.CreateDIBitmaphttps://msdn.microsoft.com/en-us/library/windows/des... (v=vs.85).aspxpakGetDChttps://msdn.microsoft.com/en-us/library/windows/des... (v=vs.85).aspxBitBlthttps://msdn.microsoft.com/en-us/library/windows/des... (v=vs.85).aspxNo a GetMem...snad jsem na nic nezapoměl.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Fakt bych neveril, ze se zaseknu na tak běžné věci, jakou musí být provnání dvou screenshotu.To co mi tady radis je fakt pro mě slozitý.takze prosim o kodeček, jak to napsat aby mi to porovnalo dva obrazky, co mám v komponente image1 a image2. Vím jak sou ty obrazky velky rozměrově (šiřka, vyška), to se řešit nemusí. A oba sou stejně veliký.Ty obrazky sou screenshoty obrazovky a lisi se jen tim, ze nekdy je na jednom červenej obdelnik. A na ten, ja chci reagovat. Ďělam si program pro poker a jak tam bude tlacitko Slozit karty, tak se mi to zmackne a samo to zahodi karty. Nejde treba zjistit adresu pameti kam si to ta komponenta ulozila?

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Pro tebe bude stačit to GetBitmapBits.Handle bitmapy znáš (...Bitmap.Handle), druhý parametr je počet bajtů (kolik bajtů budeš kopírovat) a třetí parametr je ukazatel (pointer) na data. Ten si alokuješ pomocí GetMem. Na konci musíš buffer uvolnit FreeMem.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Jo a pokud to chceš jen a pouze porovnávat a nepotřebuješ to zobrazovat, tak zbytečně na to jdeš přes TImage a TPicture. Stačí použít přímo objekt TBitmap. Jen ho nestačí naklikat, ale musíš ho ručně vytvořit.Nadeklarovat, např.var Bitmapa1, Bitmapa2: TBitmap;Objekt vytvořitBitmapa1:=TBitmap.Create;A až ho nebudeš potřebovat, tak uvolnitBitmapa1.Free;

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Ono totiž i tohle ti to asi zpomaluje, protože se musí řešit vykreslování toho objektu a tak. Pro tebe bude lepší a rychlejší s tím pracovat jen v paměti. Pak můžeš dosáhnout i třeba jednoduché zpracování obrazu + jeho překreslování v okně třeba 1000x500 pixelů 500x za sekundu, pokud to zas do okna nacpeš tím BitBlt...Delfácké komponenty jsou pomalé na tohle.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

A hlavně, abys mohl pracovat s objekty a se vším, musíš si uvědomitco je handle objektu (handle oblasti v paměti), co je instance objektu, co je pointer...co je třída objektu atd.

Souhlasím  |  Nesouhlasím  |  Odpovědět
avatar
 | Microsoft Windows 7 Firefox 47.0

Pro inspiraci:function porovnani(const Icon1, Icon2: TIcon): boolean;var ms1: TMemoryStream; ms2: TMemoryStream;begin result := false; ms1 := TMemoryStream.Create; try Icon1.SaveToStream(ms1); ms2 := TMemoryStream.Create; try Icon2.SaveToStream(ms2); if ms1.Size = ms2.Size then result := CompareMem(ms1.Memory, ms2.Memory, ms1.Size) finally ms2.free end finally ms1.free endend;procedure TForm1.Button1Click(Sender: TObject);var icon1: TIcon; icon2: TIcon;begin icon1 := TIcon.Create; icon2 := TIcon.Create; try icon1.LoadFromFile('......ico'); icon2.LoadFromFile('......ico'); If porovnani(icon1, icon2) then ShowMessage('Icon1 a Icon2 jsou stejné') else ShowMessage('Icon1 a Icon2 nejsou stejné'); finally icon1.Free; icon2.Free; end;

Souhlasím  |  Nesouhlasím  |  Odpovědět
 | Microsoft Windows 8 Opera 9.80

Tak nějak jsem žil v domění, že když ti řeknu, co bys měl hledat, že to zadáš do vyhledávače a řešení si najdeš (delphi picture comparemem). Funkční řešení bys měl do 5 minut, třeba zde:http://stackoverflow.com/questions/1352312/what-is...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.84

Tu nic není jen dlouhé poděkování, žádná otázka :) Chlapy fakt je úžasný, že mi tak pomáháte. Hned se tím začnu prokousávat a pokusím se to rozjet.. Pro vás je to určo lehoučky, nahraju do paměti porovnám a mám to. Já sem se ukazatelům vyhýbal od té doby, co sem je poznal na střední. Vím trochu jak s tím dělat, že ukazatel je adresa na misto v paměti kde jsou teprve ty data. Ale je to pro mě těžké s tím takhle nepřímo pracovat.Já sem samozdrejmě to camparemem hned zacal hledat, ale omezil sem se jen na češtinu, protože angličtina je fuj :)Tak až to vymyslim, tak se pochlubím z řešením.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Ukazatel (říkej raděj pointer), to jsou právě skvělé věci, dá se nimi dost kouzlit, a to v céčku obzvlášť, ale i v Delphi (de facto Pascal, syntakticky vychází z Pascalu). Upřímě ty TStream jsem nikdy nepotřeboval, některé věci raděj dělám přímější cestou pomocí API, je to víc "low level" a může to být i rychlejší se v tomto případě vyhnout objektům, pokud třeba zpracováváš obraz, byť takto jednoduše.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Navíc když si tu paměť pro GetBitmapBits nadeklaruješ jako pointer na pole Word, Long, nebo pokud máš 64b Delphi, tak třeba NativeUInt (64b promenná), tak neporovnáváš pouze bajty, ale "jakoby" víc bajtů najednou, až 64bitové slovo, tím se ti to zase o dost zrychlí. Deplhi komponenty jsou super, ale ne na všechno. A pak ani nemusíš použít ComapreMem, ale rovnou jeden cyklus, např. for..to.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 | Microsoft Windows 8 Opera 9.80

CompareMem je v podstate volani API (nebo assembler, ted uz si to nepamatuju) a porovnavas primo 2 kousky pameti, ktere objekty zabiraji. Podle mne ma mnohem mensi rezii, nez porovnavani v cyklu i klidne vetsich kousku.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.103

Ano, některé API fce jsou psané v assembleru, může to být rychlejší než cyklus FOR, zas tak jsem to neporovnával. Ale tak ono i záleží jak to kompilátor přeloží, nemusí to být "hrozný" kód a nevím po jak velkých "blocích" CompareMem to bere, jestli po bajtech nebo po větších. Porovnat to jde jednoduše, nechat obě vezre proběhnout několikrát v cyklu, třeba 10000x (podle potřeby), na začátku a na konci si načít systémový čas (GetSystemTime) a časy odečíst, tak si některé algoritmy odlaďuju a jde to fajně.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 | Microsoft Windows 8 Opera 9.80

Bude zalezet i na tom, jak to pojmes - algoritmus.Narazil jsem treba na tento kod:Result:=true; for y:=0 to bm1.height-1 do beginResult:=CompareMem (bm1.ScanLine[y], bm2.ScanLine[y], ScanLineLen);if not Result then exit;end;Je to docela chytre, CompareMem porovnava jednotlive radky obrazku, nesjou treba zadne streamy (dodatecna rezie). Pokud jsou obrazky odlisne, poznas to hned na prvnim radku. Samozrejme to bude pomalejsi ve srovnani pouziti funkce se streamy, pokud tam rozdil nebude nebo bude az na poslednim radku. Ale dalso by se to zase optimalizovat a porovnat prvni, prostredni a posledni radek obrazku, pokud opravdu nepotrebuju porovnat komplet vsechny pixely.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 51.0.2704.84

Chlapy makám na tom a už mi to chodí. Jste skvělí. DÍK DÍK DÍKY.Použil sem funkci na kterou odkazal pan Fiala a protoze funguje tak sem do ni ani nešahal. A dokonce jsem to zvladl i bez image komponenty. procedure TForm1.porovnejClick(Sender: TObject);var obr:Tbitmap;beginobr:=Tbitmap.Create;obr.LoadFromFile(form1.jmeno_obrazku.Text+'.bmp');if IsSameBitmap(form1.stin_img.Picture.Bitmap,obr) thenthen begin ShowMessage('stejne'); // your code for same bitmap end else begin ShowMessage('jine'); // your code for same bitmap end;obr.Free;end;nechápu teda tenhle radek, ale bez nej to nechodi. To mi taky dalo než, sem na to přišel. Já mu řeknu v sekci var, že potrebuju použivat proměnu a on mi ji stejně nevytvoří a musim si to udělat sám. Nelogický, ale akceptuju to a budu to tak používat.obr:=Tbitmap.Create;tak uzavírám kapitolu porovnávání obrázků a otevírám kapitolu, klikaní do cizí aplikace. To by ale nemel být problém, handle znam, souradnice mám a tady mam navod http://delphi.about.com/od/vclusing/a/mouseadvanc...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 | Microsoft Windows 8 Opera 9.80

obr:=Tbitmap.Create;obr.LoadFromFile(form1.jmeno_obrazku.Text+'.bmp');obr je objekt typu TBitMap. Kdyz chces s nejakym objektem pracovat, musis jej napred vytvorit.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 46.0.2486.0

To obr:=Tbitmap.Create; je naopak velmi logické. Každý objekt má constructor, který alokuje pro objekt paměť, alokuje všechny proměnné, nastavuje nějaké výchozí hodnoty proměnných atd.Na konci zas musíš paměť uvolnit, a to se dělá u některých objektůobj.Free; (např. v případě třídy TBitmap)většinou obj.Destroy; V tom VAR se alokují jen "normální" proměnné. Objekt je právě o těch pointrech. Pokud si nadeklaruješ proměnnou typu pointer (třeba PChar), tak kompilátoru je řekneš, že je to proměnná typu pointer, ale ne kolik má pro ni alokovat paměti. To musíš udělat jinde (např. tím GetMem). Takže ty mu řekneš, že obj je třídy TBitmap (ne typy, to je objekt a ty jsou o třídách, které s dají dědit...), nic víc.Nauč se práci s objekty a ukazatele, dají se s tím dělat skvělé věci a lecos to ulehčí a zpřehlední.

Souhlasím  |  Nesouhlasím  |  Odpovědět
avatar
 | Microsoft Windows 7 Firefox 47.0

Pokud programuje pro svou potřebu a neudržuje nějaké starší projekty, tak sice naučením se práce s ukazateli nic nezkazí, ale v zásadě díky vývoji hardware už tím ani zase tak moc nezíská.Vzpomeň si, jak vypadal kód programů v Delphi třeba před 20-ti lety a jak vypadá dnes. Kvůli malé operační paměti to byly samé ukazatele(^,@), а dnes ?!

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 46.0.2486.0

V případě pointerů ale vůbec nejde o velikost paměti. Tam jde o jiná kouzla. A jen tak mimochodem, prakticky vše v API, co pracuje s pamětí používá pointery. Pak např. různé dynamické pole, sice jde použít SetLength, ale také to jde pomocí pointerů..., pak třeba možnost céčkového PChar, v 64b Delphi třeba PWideChar...vše jsou pointery. Oproti Pascalova Stringu to má spoustu výhod. A tak dál, pointery jsou prostě skvělý nástroj, dá se s tím dělat spousta věcí a je to základ.Například si můžeš nadeklarovat pointer na polebData: PByteArray;druhý třeba na nuData: PNativeUInt;Alokovat paměť pro bDataa získaný pointer přiřadit i pro nuData. Pak mám dva stejné pointery pro stejnou oblast paměti, ale můžu s ní pracovat dle potřeby pomocí dvou různých polí - můžu s ní pracovat po jednotlivých bajtech i po celých 64b slovech. Někdy se to dost hodí. Je to jen příklad.A v céčku jsou pintery už úplný základ.

Souhlasím  |  Nesouhlasím  |  Odpovědět

Související témata: Picture, Then