Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Differenz zweier Bitmaps speichern (https://www.delphipraxis.net/58849-differenz-zweier-bitmaps-speichern.html)

meisteralex 13. Dez 2005 16:25


Differenz zweier Bitmaps speichern
 
Guten Tag :-)
Ich bin zur Zeit ein VNC-ähnliches Programm am proggen und wollte euch mal nach Rat fragen:
Es soll so funktionieren, dass ich die Bildschirme capture, als Bitmap speicher, die Differenz zur vorherigen aufgezeichneten Bitmap erreichen, diese mit Huffmann+LZW komprimiere und dann übertrage.
Im Moment steck ich ganz am Anfang und suche nach einem optimiertem Verfahren um 2 Bitmaps miteinander zu vergleichen und die Differenz zu speichern.
Das Verfahren sollte zimich schnell sein. Hat jemand eine Idee ???

etom291272 13. Dez 2005 20:55

Re: Differenz zweier Bitmaps speichern
 
ich hab vor kurzem so ein remote tool mit delphi realisiert. ich sag dir gleich du nimmst dir einiges vor. warum willst du das selber schreiben?

ich habs genau so gemacht allerdings unterteile ich den schirm in 8 horizontale zonen und frage jede zone einzeln ab und übertrage dann die differenz (trotzdem bei isdn ätzend langsam).

mit dieser methode kannst du die anzahl der unterschiedlichen pyxel in 2 bitmaps feststellen
Delphi-Quellcode:
function TMainFormClient.BitmUnterschVorh(Bitm1, Bitm2:TBitmap):Boolean;
var
  y, x: integer;
  P, P2: PByteArray; //  PRGBTriple; // PRGBQuad def. in Unit Windows;
  CountFalsePixel: Integer;

  aRect: TRect;
begin
  aRect := Rect(65000, 65000, 0, 0);
  CountFalsePixel := 0;

  // Bitmaps vergleichen
  for y := 0 to Bitm1.Height - 1 do
  begin
    P := Bitm1.ScanLine[y];
    P2 := Bitm2.ScanLine[y];
    for x := 0 to Bitm1.Width - 1 do
    begin
     if (P[x] <> P2[x]) then
     begin
        Inc(CountFalsePixel);
        begin
          if x < aRect.Left then
            aRect.Left := x;
          if y < aRect.Top then
            aRect.Top := y;
          if x > aRect.Right then
            aRect.Right := x;
          if y > aRect.Bottom then
            aRect.Bottom := y;
        end;//rect
     end;//Unterschied
    end;//xlauf
  end;//y lauf

  {ShowMessage('Das Ausführen dauerte '+IntToStr(GetTickCount - FirstTickCount)+' Ticks'+
              chr(13)+'Unterschiede: '+inttostr(CountFalsePixel)+chr(13)+
              'Anzahl Items Liste: '+inttostr(ListBox1.Items.Count));}

  if CountFalsePixel>0 then result:=True
  else Result:=False;
end;

meisteralex 14. Dez 2005 06:57

Re: Differenz zweier Bitmaps speichern
 
wenn das so ätzend langsam ist, wie schafft es dann vnc ?
ich mein die können doch auch nicht zaubern.
kennt jemand das prizip von denen?? hab jetzt keine lust, mir den quellcode anzugucken, weiß nur das die mit jpeg kompression arbeiten.

MarcoWarm 14. Dez 2005 08:05

Re: Differenz zweier Bitmaps speichern
 
Ich wandle die Bilder vor dem Versenden in PNGs um ... Das bedeutet zwar ein bissl mehr Prozessorlast auf dem "überwachten" Rechner ... aber beim "Überwacher" kommen kleine Bildpackete an, die auch noch ordentlich aussehen (nicht wie bei JPEG). Ausserdem kann man ja PNG nur die wirklich sichtbaren Daten übertragen (alles andere wird einfach Transparent). Desweiteren werden bei mir nur Daten übertragen, wenn sich mehr Bildpunkte ändern, als in einem userdefinierten Schwellenwert definiert.

meisteralex 14. Dez 2005 08:15

Re: Differenz zweier Bitmaps speichern
 
hört sich gut an, hasst du vielleicht nen beispielcode ??

etom291272 14. Dez 2005 08:20

Re: Differenz zweier Bitmaps speichern
 
@marco warm
wie gross sind den bei dir dann die datenpakete wenn ein teil des Bildschirms neu aufgebaut wird.

bei meiner horizontal split methode sind die zu übertragenden pakete teilweise nur 5kb gross aber bei
8 bildteilen können da schon auch mal 80 -100 kb zusammenkommen und dann bei isdn :kotz:

@all
ich glaube nicht dass die gängigen remote prgs bildteile des zu wartenden pc's herumschicken dass muss irgenwie anders gehen.

ganz zu schweigen von der rdp technologie bzw citrix (geht ja fast in echtzeit bei isdn) hab auch schon im netz intensiv gestöbert wie das bei terminalserver gelöst ist habe aber nichts konkretes gefunden.

mein prg läuft jetzt zwar durchaus zufriedenstellend bei >=128k upload des zu wartenden netzwerks bin aber sehr interessiert daran dass Verfahren zu beschleunigen.

MarcoWarm 14. Dez 2005 09:22

Re: Differenz zweier Bitmaps speichern
 
@ etom

typische Packetgrößen bei einer "Beobachtung" eines unserer User im Adobe Illustrator:
- ganzer Bildschirm (1280x1024) ... Das Bild wird aller 30 Bilder als neues "Schlüsselbild" gepollt:
ca 36 kb
- Dateimenü öffnen
1,26 kb
... mist, jetzt hat sie das Programm gewechselt lol
- Textverarbeitung blinkender Cursor
0,83kb
- rumnavigieren mit dem Explorer
1-3 kb

es kann eigentlich nur so gehen, daß Bildteile verschickt werden. Ich denke Citrix benutzt ein sehr intelligentes Komprimierungs und Bitmap-Caching Verfahren.

Cicaro 14. Dez 2005 10:29

Re: Differenz zweier Bitmaps speichern
 
Also zum Thema Bildvergleich und ähnliches kommt mir ersteinmal die Idee, die beiden Bitmaps mit Hilfe der API-Funktion BitBlt() zu verknüpfen.
Wenn man die DCs der Bitmaps hat, sollte man mit der richtigen AND-OR-NOT-Technik die Differenz der beiden Bitmaps erhalten können.

Spontan würde ich sagen, es müsste mit
Delphi-Quellcode:
// DC1 von Bitmap1, DC2 von Bitmap2
(DC1 or DC2) // entspricht BitBlt(DC1,0,0,Width1,Height1,DC2,0,0,SRCPAINT);

( DC1 and ( not ( DC1 and DC2 )) // vorgeschlagene Lösung
gehen.
Wenn ich mit dem Code Recht hab' ist die Berechnung des Bildunterschiedes in dem Fall rasant.
Wichtig: man sollte die passenden Bildverknüpfungskonstanten - wie SRCPAINT für OR - aus der Delphi-Hilfe heraussuchen.

meisteralex 14. Dez 2005 12:28

Re: Differenz zweier Bitmaps speichern
 
jetzt versteh ich nur noch bahhof *g*

meisteralex 14. Dez 2005 14:47

Re: Differenz zweier Bitmaps speichern
 
hat sich jemand von euch schonmal gedanken darüber gemacht ein remote - tool zu schreiben welches anders arbeitet als nach der bildschirmabfotografier-methode. rdc von ms macht das ja auch irgendwie und netop kann soweit ich weiß auch den bildschirminhalt anhand von Windows-Aufrufe übertragen..
Hat irgendjemand ne Idee wie das Funktionieren könnte `?

Cicaro 15. Dez 2005 10:14

Re: Differenz zweier Bitmaps speichern
 
Zitat:

Zitat von meisteralex
jetzt versteh ich nur noch bahhof *g*

Wie gesagt sollte man nach den RICHTIGEN Konstanten in der Delphi-Hilfe suchen.
Hier der Code noch mal ausführlicher:
Delphi-Quellcode:
procedure DifZweierBilder(ZielDC,DC1,DC2:HDC);
begin
  // ( DC1 and ( not ( DC1 and DC2 )) damit sollte folgendes ausgedrückt werden
  // erstmal kopieren
  BitBlt(ZielDC,0,0,1024,768,DC1,0,0,SRCCOPY);
  // die innere UND-Verknüpfung
  BitBlt(DC1,0,0,1024,768,DC2,0,0,SRCAND);
  // die UND-NICHT verknüpfung
  BitBlt(ZielDC,0,0,1024,768,DC1,0,0,NOTSRCAND);
end;

// Aufruf durch
DifZweierBilder(ZielCanvas.Handle,Canvas1.Handle,Canvas2.Handle);

meisteralex 20. Dez 2005 13:06

Re: Differenz zweier Bitmaps speichern
 
notsrcand gibt es bei mir nicht ???

meisteralex 20. Dez 2005 13:16

Re: Differenz zweier Bitmaps speichern
 
wie mach ich das denn nun ??

also ich bekomme mit

bitblt(dc2,0,0,W,H,dc1,0,0,mergepaint)

schon so zimich genau die differenz der beiden bilder hin
wie komme ich jedoch mit hilfe von dc1 und der differenz, welche nun in dc2 liegt, wieder zum ausgangsbild dc2 ???

also nochmal
ich hab dc1 (vor veränderung) und dc2 (nach veränderung)
mit bitblt(dc2,0,0,W,H,dc1,0,0,mergepaint) liegt nun in dc2 die eigentliche veränderung (reduziert auf die teile die sich auch wirklich verändert haben)
wie bekomme ich nun aus dc1 und dc2 wieder das ehemalige dc2, also das komplette bild und nicht nur die veränderungen??
wäre sehr nett wenn mir da jemand helfen könnte

ichbins 20. Dez 2005 13:25

Re: Differenz zweier Bitmaps speichern
 
vllt mit einer or-Verschaltung.

meisteralex 20. Dez 2005 13:34

Re: Differenz zweier Bitmaps speichern
 
nö, dann kommt bei mir wieder dc1 raus, das bring mir ja nix, will ja dc2 haben

ichbins 20. Dez 2005 13:47

Re: Differenz zweier Bitmaps speichern
 
nein, du hast ja auf dem Kontrollrechner schon ein komplettes Bild gespeichert. Jetzt musst du dieses ja mit den Werten, die per ISDN reingetrudelt kommen, ergänzen. Wenn du ein PNG-Bild hast, würde einfach canvas.draw reichen: zielbmp.canvas.draw(0,0,png);

meisteralex 21. Dez 2005 07:53

Re: Differenz zweier Bitmaps speichern
 
jo habs hinbekommen :-) jetzt nur noch einne frage

wenn ich die differenz zweier bitmaps mit bitblt errechne bekomme ich, falls die bilder gleich sind als differenz ein schwarzes bild (keine differenz wird bei scrinvert zu schwarz).
wie kann ich jetzt in meiner routine prüfen ob die beiden bilder überhaupt einen unterschied hatten.
wenn ich jetzt mit scanline arbeite wäre der geschwindigkeitsvorteil von bitblt ja zu nichte. gibt es eine funktion die z.b. prüft wieviel farben in einer bitmap sind, oder hat jemand ne andere idee ???

etom291272 21. Dez 2005 11:42

Re: Differenz zweier Bitmaps speichern
 
:mrgreen: nicht bös sein aber wer lesen kann ist klar im vorteil :zwinker:

in meinem post auf seite 1 hast du die komplette methode zum rauskopieren ob sich die bitmaps unterscheiden oder nicht.

meisteralex 21. Dez 2005 14:23

Re: Differenz zweier Bitmaps speichern
 
hmm, aber dass ist ja wieder mit dem langsamen scanline realisiert ??
da kann ich ja alles darüber laufen lassen, wenn ich das schnelle bitblt mit dem langsamen scanline ausbremse

etom291272 21. Dez 2005 14:52

Re: Differenz zweier Bitmaps speichern
 
das ist schnell genug hab ich mit tickcount überprüft.

meisteralex 21. Dez 2005 20:43

Re: Differenz zweier Bitmaps speichern
 
welchen code meinst du denn jetzt genau ?? also bei mir brauch die scanline - methode 10x so viel wie die bitblt methode

Cicaro 22. Dez 2005 09:08

Re: Differenz zweier Bitmaps speichern
 
Zitat:

Zitat von meisteralex
wie mach ich das denn nun ??

also ich bekomme mit

bitblt(dc2,0,0,W,H,dc1,0,0,mergepaint)

schon so zimich genau die differenz der beiden bilder hin
wie komme ich jedoch mit hilfe von dc1 und der differenz, welche nun in dc2 liegt, wieder zum ausgangsbild dc2 ???

also nochmal
ich hab dc1 (vor veränderung) und dc2 (nach veränderung)
mit bitblt(dc2,0,0,W,H,dc1,0,0,mergepaint) liegt nun in dc2 die eigentliche veränderung (reduziert auf die teile die sich auch wirklich verändert haben)
wie bekomme ich nun aus dc1 und dc2 wieder das ehemalige dc2, also das komplette bild und nicht nur die veränderungen??
wäre sehr nett wenn mir da jemand helfen könnte

Ich bin mir jetzt nicht sicher, wie du die Differenz zweier Bitmaps definiers. Was ich vorzuschlagen versuche, ist, dass man die beiden DCs der beiden Bitmaps so durch BitBlt verknüpft, dass man DIE Bits, die in den Pixeln an der gleichen Stelle gleich sind, durch NULL ersetzt. Das Ergebnis sollte dann in einem dritten Bitmap gespeichert werden.
Delphi-Quellcode:
// Beispiel (theoretisch):
// Vergleich von
Bitmap1.Canvas.Pixels[0,0] = 010101010101010101010101
Bitmap2.Canvas.Pixels[0,0] = 001100110011001100110011
// herauskommen sollte, wenn Bitmap1-Bitmap2:
Bitmap3.Canvas.Pixels[0,0] = 010001000100010001000100
// für Bitmap2-Bitmap1 sieht es dann etwas anders aus
Das sollte mit BitBlt gehen.

Vielleicht hilft das was, wenn du in der Unit 'Windows.pas' mal nach den Konstanten SRCPAINT und SRCCOPY suchst. Da stehen einige einleuchtende erläuterungen dabei.

Da die Differenz zweier Bitmaps ein scheinbar so großes Problem darstellt :gruebel: , werd' ich mich mal mit der Lösung etwas genauer befassen...

meisteralex 22. Dez 2005 15:03

Re: Differenz zweier Bitmaps speichern
 
jo hab jetzt den optimalen code gefunden *g*
nachdem ich hier die tips bekommen habe, hab ich einfach alle möglichkeiten mal durchgetestet.
der errechnet die differenz allein mit bitblt und rechne mit vorherigem bild + differenz das neue bild aus.
vielen dank nochmal für die hilfe, wenn den code jemand haben will dann postet hier.

etom291272 22. Dez 2005 15:04

Re: Differenz zweier Bitmaps speichern
 
wie gross sind die differenzbilder ?

Cicaro 23. Dez 2005 08:41

Re: Differenz zweier Bitmaps speichern
 
Zitat:

Zitat von meisteralex
wenn den code jemand haben will dann postet hier.

Da ich immer noch nicht wirklich weiß, was du unter Differenz zweier Bitmaps verstehst, würd ich mir mal den "fertigen" Code gern ansehen.

alleinherrscher 28. Feb 2007 15:08

Re: Differenz zweier Bitmaps speichern
 
Sorry, wenn ich hier n totes Thema nochmal auferstehen lasse.

Aber könnte mir evtl jemand auf die sprünge helfen, wie die Jungs das hier schlussendlich realisiert haben? ich habe mit bitblt und Mergepaint rumexperimentiert aber bekomme hinterher nie die änderung so auf das alte Bild, dass daraus das neue Bild entsteht...

im Augenblick benutze ich

Delphi-Quellcode:
  BitBlt(ZielDC,0,0,1024,768,DC2,0,0,SRCcopy);
  bitblt(zielDC,0,0,1024,768,dc1,0,0,MERGEPAINT);
und zum zusammenfügen einfach den drawbefehl, kommt aber nur käse bei raus.


Ne Antwort von euch wäre echt klasse und sorry nochmal dass ich den alten thread nochmal neustarte.

Grüße
Alleinherrscher


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz