Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bilder vergleichen unterschiede platzsparend abspeichern (https://www.delphipraxis.net/56280-bilder-vergleichen-unterschiede-platzsparend-abspeichern.html)

etom291272 3. Nov 2005 08:53


Bilder vergleichen unterschiede platzsparend abspeichern
 
:-D
Guten Tag zusammen

mit diesem Code

Delphi-Quellcode:
var
  y, x: integer;
  P, P2: PRGBTriple; // PRGBQuad def. in Unit Windows;
  CountFalsePixel, FirstTickCount: Integer;
  aRect: TRect;
  MemBmp: TBitmap;
begin
  CountFalsePixel := 0;
  FirstTickCount := GetTickCount;
  // 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 RGB(P^.rgbtRed, P^.rgbtGreen, P^.rgbtBlue) <>
        RGB(P2^.rgbtRed, P2^.rgbtGreen, P2^.rgbtBlue) then
      begin
        Inc(CountFalsePixel);
      end;
      Inc(P);
      Inc(P2);
    end;
  end;
   ShowMessage('Das Ausführen dauerte '+IntToStr(GetTickCount - FirstTickCount)+' Ticks'+
              chr(13)+'Unterschiede: '+inttostr(CountFalsePixel));
end;
vergleiche ich recht flott 2 bitmaps (bei grösse 1024 x 768 dauert dass ca 30 ticks) nun möchte ich
die unterschiedlichen pixel mit ihrer information also posx, posy und farbe platzsparend speichern
(stream). Bei meinen bisherigen versuchen wurde der stream bei völlig unterschiedlichen Bildern grösser als dass eigentliche bitmap. :wall:

wenn sich das Bild sagen wir um 400000 pixel unterscheidet bei gesamtpixel von 786432 möchte ich mit
10 - 15kb grösse auskommen
:?: ist das möglich
:?: wenn ja wie

Danke für eure Hilfe :coder:

Der_Unwissende 3. Nov 2005 09:11

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
Hi,
also ohne jetzt sehr detailiert drüber nachgedacht zu haben, mal zwei Ansätze. Als erstes könntest du (wenig optimiert) einfach eine 1024x768 Matrix anlegen, die an jeder Stelle nur speichert ob sich ein Pixel unterscheidet oder nicht (also boolsch).
Optimaler ist es aber, das ganze als Liste zu verwalten.
Wieder der weniger Platzsparende Weg (aber perfomanter) wäre es, sich einfach ein Array der Größe 768 anzulegen und für jede Zeile Tupel zu speichern. Dabei steht in jedem Tupel das Paar x1, x2 wobei natürlich jede Zeile des Arrays = Zeile deiner Bitmap ist und jedes Tupel die Start- und Endkoordinate der sich unterscheidenden Pixel angibt. Wenn diese benachbart sind, sparst du so schon etwas platz.
Eine optimiertere Möglichkeit was den Platz angeht wäre es dann natürlich nur noch die Zeilen (mit Index der Zeile) zu speichern, die wirklich Pixel enthalten, die sich unterscheiden.

Hm, sollten die aber sehr gut verteilt liegen wird es schwierig deine Grenze einzuhalten. Du hättest ansonsten das Problem, dass eine Bitmatrix (z.B. als gesetzte oder nicht gesetze Bits von 32 Integers pro Zeile) zu einer 768*32*4 Byte Matrix führen würde = ca. 98 KByte (wenn ich mich nicht verrechnet habe.

Gruß Der Unwissende

Flocke 3. Nov 2005 09:18

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
Auch aus der Hüfte geschossen:

1. Bilde die Differenz zwischen dem alten und dem neuen Bild (z.B. einfach die RGB-Werte voneinander abziehen) und speichere das Ergebnis in einem 24-Bit-Stream.
2. Wende auf diesen Stream ein verlustfreies Komprimierungsverfahren an.

Das andere Programm kann dann aus dem alten Bild und den Differenzdaten das neue Bild erstellen. Dort wo die Bilder gleich sind, erhälst du eine lange Kette mit Nullen, die von einer Komprimierung normalerweise fast auf die Länge 0 reduziert werden.

// Noch ein Nachtrag: nicht jeder hat 24-Bit Farbtiefe eingestellt, möglich sind 4, 8, 16, 24 oder 32.

tommie-lie 3. Nov 2005 09:24

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
Zitat:

Zitat von etom291272
nun möchte ich die unterschiedlichen pixel mit ihrer information also posx, posy und farbe platzsparend speichern
[...]
wenn sich das Bild sagen wir um 400000 pixel unterscheidet bei gesamtpixel von 786432 möchte ich mit
10 - 15kb grösse auskommen

Selbst wenn es ein Bild mit nur 256 Farben ist, wäre das ein Byte pro Pixel, bei 400000 Pixeln also 400000 Byte ~ 390 kiB. Vielleicht kriegst du das Verlustfrei (Bzip2) auf 15 kiB zusammengeschrumpft, aber bei einem TrueColor-Bild sind es ja schon über 1,5 MiB, die kriegst du bei zufälligen Bilddaten bestimmt nicht auf 15kiB. Und die Rechnung betraf ja nur die Farbwerte, für ein 1024x786-Bild brauchst du für jede x- und y-Koordinate nochmal ein Word, insgesamt für ein 1024*786-TrueColor-Bild also 8 Byte pro Pixel. Du kannst es zwar nach des unwissenden zweiter Methode machen (nur die unterschiedlichen Stripes einer Bitmap-Zeile speichern) machen, das spart deutlich an Speicherplatz für die Pixelkoordinaten, aber wenn du sämtliche Farbwerte verlustfrei unterbringen willst, kriegst du's wahrscheinlcih nicht so klein.

Der_Unwissende 3. Nov 2005 09:35

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
Oh, seh gerade dass ich übersehen habe, dass die Farbe auch gespeichert werden soll, ja das relativiert die Rechnung. Denke mal dein Platzbedarf wird dir gar nicht garantiert werden können, aber auch im Mittel dürfte er deutlich drüber liegen. Die Wahrscheinlichkeit das viele benachbarte Pixel exakt die gleiche Farbe haben ist doch eher gering. Und auch bei guter Kompression dürften 15Kbyte ziemlich wenig sein.

etom291272 3. Nov 2005 13:34

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
Zitat:

Selbst wenn es ein Bild mit nur 256 Farben ist, wäre das ein Byte pro Pixel, bei 400000 Pixeln also 400000 Byte ~ 390 kiB. Vielleicht kriegst du das Verlustfrei (Bzip2) auf 15 kiB zusammengeschrumpft,
die idee mit den 256 farben gefällt mir bei meinem test wo sich ca 1/3 des schirms ändert beträgt der stream nur noch 210 kb gezippt dann 8kb :thumb:

Aber :oops: :oops:

ich mache noch einen fehler wie ich die farben abspeichere.
ich versuche über scanline einen zeiger auf die linie zu erhalten und lese dann jeden teil des arrays (was ja dann eigentlich das byte sein müsste aus)
Delphi-Quellcode:
P, P2: PByteArray;
...
for x := 0 to Bitm1.Width - 1 do
    begin
      if (P[x] <> P2[x]) then
     begin
        Inc(CountFalsePixel);
        Inc(aLauf);
        Daten[aLauf].Farbe:= P2[x];
...
in daten i sind dann auch werte zwischen 0 und 255 aber ich fürchte dass entspricht nicht der farbe

in anderes bitmap einlesen dann so

Delphi-Quellcode:
  for i:=0 to 200000 do   //Length(Daten) -1 do
  begin
    inc(AktSpalte);
    Image2.Picture.Bitmap.Canvas.Pixels[AktZeile,AktSpalte]:=Daten[i].Farbe;
    if AktSpalte = 100 then inc(AktZeile);
    if AktSpalte>100 then AktSpalte:=-1;
  end;
  ShowMessage('fertig'+' Anzahl Items Liste: '+inttostr(ListBox1.Items.Count));
er zeichnet zwar aber nur rot
kann man nur mit einem byte eine farbe bei einem pf8bit bitmap abspeichern :?:

tommie-lie 3. Nov 2005 16:46

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
Zitat:

Zitat von etom291272
gezippt dann 8kb :thumb:

Wow, das lässt sich ja wesentlich besser komprimieren als ich gedacht hätte :shock:

Zitat:

Zitat von etom291272
er zeichnet zwar aber nur rot

Beinhaltet denn die Bitmap-Instanz der Image-Komponente bei dir ebenfalls ein 8bit-Bitmap, oder ist das auf 32 oder 24 Bit eingestellt?

etom291272 3. Nov 2005 16:48

Re: Bilder vergleichen unterschiede platzsparend abspeichern
 
ich hatte nicht gecheckt dass wenn ich ein byte abspeichere dass nicht die farbe ist sondern nur ein indexverweis auf die farbtabelle :oops:


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:17 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