![]() |
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 ??? |
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; |
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. |
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.
|
Re: Differenz zweier Bitmaps speichern
hört sich gut an, hasst du vielleicht nen beispielcode ??
|
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. |
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. |
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:
gehen.
// 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 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. |
Re: Differenz zweier Bitmaps speichern
jetzt versteh ich nur noch bahhof *g*
|
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 `? |
Re: Differenz zweier Bitmaps speichern
Zitat:
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); |
Re: Differenz zweier Bitmaps speichern
notsrcand gibt es bei mir nicht ???
|
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 |
Re: Differenz zweier Bitmaps speichern
vllt mit einer or-Verschaltung.
|
Re: Differenz zweier Bitmaps speichern
nö, dann kommt bei mir wieder dc1 raus, das bring mir ja nix, will ja dc2 haben
|
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);
|
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 ??? |
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. |
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 |
Re: Differenz zweier Bitmaps speichern
das ist schnell genug hab ich mit tickcount überprüft.
|
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
|
Re: Differenz zweier Bitmaps speichern
Zitat:
Delphi-Quellcode:
Das sollte mit BitBlt gehen.
// 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 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... |
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. |
Re: Differenz zweier Bitmaps speichern
wie gross sind die differenzbilder ?
|
Re: Differenz zweier Bitmaps speichern
Zitat:
|
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:
und zum zusammenfügen einfach den drawbefehl, kommt aber nur käse bei raus.
BitBlt(ZielDC,0,0,1024,768,DC2,0,0,SRCcopy);
bitblt(zielDC,0,0,1024,768,dc1,0,0,MERGEPAINT); 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 20:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz