Announcement

Collapse
No announcement yet.

Bilder vergleichen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bilder vergleichen

    Hallo,

    ich habe einen ordner a und einen ordner b und in beiden ordnern sind bilder!
    die bilder heißen aber in den ordnern unterschiedlich!
    jetzt möchte ein bild von ordner a in ordner b löschen!

    auf gut deutsch, ich möchte zwei bilder <b>pixelmäßig</b> vergleichen!

    wie macht man das?

    Gruß

    Markus
    Herzliche Grüße

    Markus Lemcke
    barrierefreies Webdesign

  • #2
    Hi Markus.
    .
    Ich würde die Bilder in eine (zwei) Bitmap laden und dann Pixel für Pixel auslesen und die ergebenden Farben voneinander abziehen.
    Dann kannst Du die Pixel zählen, wo 0 (schwarz) als Farbe rauskommt und ins Verhältnis zu den Gesamtpixeln setzen.
    Dann nur noch mit dem Schwellenwert vergleichen, an dem Du festmachst, ob die Bilder gleich sind.
    .
    An die Grafikexperten: Gibts bessere Methoden?
    .
    mfg
    Michae

    Comment


    • #3
      Hallo!

      Vielleicht hilft:
      <a href="/webx?50@@.4a872a35">Bernd Schulz "Bilder vergleichen" 09.03.2005 11:26</a>

      Als Stand Alone Programm kann ich (aus eigener Erfahrung)
      http://www.uniquefiler.com/
      empfehlen.

      BYE BERN

      Comment


      • #4
        hi bernd!

        möchte es ohne externe komponente hinbekommen!
        probiere mal michaels idee!

        danke!

        Gruß

        Marku
        Herzliche Grüße

        Markus Lemcke
        barrierefreies Webdesign

        Comment


        • #5
          hi,

          habe das hier aus dem netz:
          <pre>
          procedure TForm1.Button1Click(Sender: TObject);
          var
          b1, b2: TBitmap;
          c1, c2: PByte;
          x, y, i,
          different: Integer; // Counter for different pixels
          begin
          b1 := Image1.Picture.Bitmap;
          b2 := Image2.Picture.Bitmap;
          Assert(b1.PixelFormat = b2.PixelFormat); // they have to be equal
          different := 0;
          for y := 0 to b1.Height - 1 do
          begin
          c1 := b1.Scanline[y];
          c2 := b2.Scanline[y];
          for x := 0 to b1.Width - 1 do
          for i := 0 to <b>BytesPerPixel</b> - 1 do // 1, to 4, dep. on pixelformat
          begin
          Inc(different, Integer(c1^ <> c2^));
          Inc(c1);
          Inc(c2);
          end;
          end;
          end;
          </pre>

          woher kommt <b>BytesPerPixel</b>?
          mein Delphio kennt das nicht!

          gruß

          marku
          Herzliche Grüße

          Markus Lemcke
          barrierefreies Webdesign

          Comment


          • #6
            Hallo <p>
            So wie es im Kommentar, steht 1 (eins) bis 4 (vier).
            Das ist dann wohl etwas kompizierter ...
            <p>
            Heik

            Comment


            • #7
              das hier:
              <pre>
              //Wenn gleich dann true, sonst false
              function JpgVergleich(BildDateiA,BildDateiB : String) : boolean;
              var
              JpgA, JpgB: TJpegImage;
              BmpA, BmpB: TBitmap;
              x, y,
              different: Integer; // Counter for different pixels
              begin
              result := true;
              JpgA := TJPEGImage.Create;
              JpgB := TJPEGImage.Create;

              BmpA := TBitmap.Create;
              BmpB := TBitmap.Create;

              try
              JpgA.LoadFromFile(BildDateiA);
              JpgB.LoadFromFile(BildDateiB);

              BmpA.Assign(JpgA);
              BmpB.Assign(JpgB);

              if JpgA.Height <> JpgB.Height then
              begin
              Result := false;
              exit;
              end;

              if JpgA.Width <> JpgB.Width then
              begin
              Result := false;
              exit;
              end;

              if JpgA.PixelFormat <> JpgB.PixelFormat then
              begin
              Result := false;
              exit;
              end;

              for x := 0 to BmpA.Width-1 do
              begin
              for y := 0 to BmpB.Height-1 do
              begin
              if BmpA.Canvas.Pixels[x,y] <> BmpB.Canvas.Pixels[x,y]
              then Result := false;
              end;
              end;
              finally
              JpgA.Free;
              JpgB.Free;
              BmpA.Free;
              BmpB.Free;
              end;
              end;
              </pre>

              funzt, aber schnell ist die sache nicht!

              Gruß

              Marku
              Herzliche Grüße

              Markus Lemcke
              barrierefreies Webdesign

              Comment


              • #8
                Wenn ich mich richtig an meine Delphi-Zeiten erinnere war "Pixels[x,y]" nie besonders schnell. Einen deutlichen Performance-Gewinn sollte z.B. der Einsatz der GDI-Funktionen bringen (Windows API).
                Interessant wäre da noch die Frage: Müssen die Bilder wirklich 100% gleich sein oder genügt es, vielleicht nur jedes 2. oder 3. oder n.te Pixel zu vergleichen !?

                Viele Grüße H

                Comment


                • #9
                  habe das hier versucht:
                  <pre>
                  procedure BildVergleich(Bild1, Bild2: string);
                  var
                  VBild1, VBild2: file of byte;
                  BufferBild1,BufferBild2: array[0..4096] of char;
                  NumRead: integer;
                  FileLength: longint;
                  Vdifferent : boolean;
                  begin
                  Vdifferent := false;
                  AssignFile(VBild1, Bild1);
                  reset(VBild1);
                  AssignFile(VBild2, Bild2);
                  rewrite(VBild2);
                  FileLength := FileSize(VBild1);
                  while FileLength > 0 do
                  begin
                  BlockRead(VBild1, BufferBild1[0], SizeOf(BufferBild1), NumRead);
                  FileLength := FileLength - NumRead;
                  BlockRead(VBild2, BufferBild2[0], SizeOf(BufferBild2), NumRead);
                  if BufferBild1[0] <> BufferBild2[0] then
                  begin
                  Vdifferent := true;
                  break;
                  end;
                  end;
                  CloseFile(VBild1);
                  CloseFile(VBild2);
                  if Vdifferent then ShowMessage('Bilder sind verschieden!')
                  else ShowMessage('Bilder sind gleich!');
                  end;
                  </pre>

                  funzt aber nicht! bilder sind immer gleich!

                  warum?

                  gruß

                  Marku
                  Herzliche Grüße

                  Markus Lemcke
                  barrierefreies Webdesign

                  Comment


                  • #10
                    Es sollte auch durch die Verwendung von TBitmap::Scanline eine deutliche Perfomancesteigerung möglich sein. Das sollte sich relativ einfach in der ersten Routine ändern lassen

                    Comment


                    • #11
                      schneller wie blockread?
                      ich habe es nun, so fuzt es!
                      <pre>
                      (*
                      Zweck: Vergleichen zum Dateien. Wird in der MotoScout24-Schnittstelle
                      zum Vergleichen von Bildern verwendet
                      Rückgabe: Wenn beide Dateien gleich sind, wird True zurückgegeben,
                      sonst False!
                      *)

                      function DateiVergleich(Datei1, Datei2: string) : boolean;
                      var
                      VDatei1, VDatei2: file of byte;
                      BufferDatei1,BufferDatei2: array[0..1] of char;
                      NumRead: integer;
                      FileLength: longint;
                      begin
                      Result := True;
                      AssignFile(VDatei1, Datei1);
                      AssignFile(VDatei2, Datei2);
                      reset(VDatei1);
                      reset(VDatei2);
                      try
                      //Dateigröße vergleichen
                      if FileSize(VDatei1) <> FileSize(VDatei2) then
                      begin
                      //Dateien nicht gleich
                      Result := False;
                      exit;
                      end;

                      FileLength := FileSize(VDatei1);

                      //Byteweiser Vergleich
                      while FileLength > 0 do
                      begin
                      BlockRead(VDatei1, BufferDatei1[0], SizeOf(BufferDatei1), NumRead);
                      FileLength := FileLength - NumRead;
                      BlockRead(VDatei2, BufferDatei2[0], SizeOf(BufferDatei2), NumRead);
                      if BufferDatei1[0] <> BufferDatei2[0] then
                      begin
                      //Dateien nicht gleich
                      Result := False;
                      break;
                      end;
                      end;
                      finally
                      CloseFile(VDatei1);
                      CloseFile(VDatei2);
                      end;
                      end;
                      </pre>

                      könnte nicht behaupten, dass es langsam ist!

                      gruß

                      marku
                      Herzliche Grüße

                      Markus Lemcke
                      barrierefreies Webdesign

                      Comment


                      • #12
                        okay, bei dateien über 1 mb dauert es 2 sekunden!

                        vielleicht kann jemand mal die <b>schnellere</b> lösung bitte posten
                        Herzliche Grüße

                        Markus Lemcke
                        barrierefreies Webdesign

                        Comment


                        • #13
                          Hallo Markus,

                          mal abgesehen davon, dass Du jedes zweite Byte nicht vergleichst, (Du liest immmer 2 Bytes in den Puffer, vergleichst aber immer nur das erste(nullte)) ist Deine function deshalb so langsam, weil Du immer nur zwei Bytes liest.

                          Lese größere Blöcke (4k) und dann geht es ab.

                          Etwa so (Ich habe den Code blind (ohne Compiler) geändert, hoffe er compiliert)

                          function TForm1.DateiVergleich(Datei1, Datei2: string) : boolean;
                          const
                          bufSize = 4096;
                          var
                          VDatei1, VDatei2: file of byte;
                          BufferDatei1,BufferDatei2: array[0..bufsize-1] of Byte;
                          NumRead1, Numread2: integer;
                          i : Integer;
                          begin
                          Result := True;
                          AssignFile(VDatei1, Datei1);
                          AssignFile(VDatei2, Datei2);
                          reset(VDatei1);
                          reset(VDatei2);
                          try
                          //Dateigröße vergleichen
                          if FileSize(VDatei1) <> FileSize(VDatei2) then
                          begin
                          //Dateien nicht gleich
                          Result := False;
                          exit;
                          end;
                          repeat
                          BlockRead(VDatei1, BufferDatei1[0], SizeOf(BufferDatei1), NumRead1);
                          BlockRead(VDatei2, BufferDatei2[0], SizeOf(BufferDatei2), NumRead2);
                          if NumRead1 <> Numread2 then begin
                          // Sollte nie passieren, da schon oben Filesizes verglichen.
                          Result := false;
                          exit;
                          end;
                          if Numread1 = 0 then begin
                          // Nix mehr da, also raus
                          exit;
                          end;

                          for i := 0 to bufsize -1 do begin
                          if BufferDatei1[i] <> BufferDatei2[i] then
                          begin
                          //Dateien nicht gleich
                          Result := False;
                          break;
                          end;
                          end;
                          until false;

                          finally
                          CloseFile(VDatei1);
                          CloseFile(VDatei2);
                          end;
                          end;

                          Das geht noch schöner, sollte aber das Prinzip zeigen.
                          Ausserdem wäre eine ordentlich Fehlerbehandlung angebracht und das try hinter den beiden resets ist auch nix. Wenn die erste Datei geöffnet werden kann, die zweite aber nicht bleibt die erste offen.

                          Gruß
                          Pete

                          Comment


                          • #14
                            Hallo Peter,

                            danke! ich schaue es mir mal an!

                            gruß

                            Marku
                            Herzliche Grüße

                            Markus Lemcke
                            barrierefreies Webdesign

                            Comment


                            • #15
                              Der Vergleich der Blöcke kannst du auch mit der Funktion

                              CompareMem(P1, P2: Pointer; Length: Integer):

                              <for i := 0 to bufsize -1 do begin
                              < if BufferDatei1[i] <> BufferDatei2[i] then
                              < begin
                              < //Dateien nicht gleich
                              < Result := False;
                              < break;
                              < end;
                              <end;

                              result := CompareMem ( BufferDatei1[0],BufferDatei2[0],BufSize );

                              Gruß

                              Cesari

                              Comment

                              Working...
                              X