title: What is the fastest solution to compare JPEG image? (ignoring metadata, just the "pixels")
body: <p>When I search the words "JPEG" and "metadata", I have many answers to manipulate the metadata... and this is the opposite I want... ;o)</p>
  
  <p>I have written a function which exactly works like I want... (if images are similar, and only the metadata change or not, the function returns <code>True</code> ; if at least one pixel changes, it returns <code>False</code>) but, I'd like to improve the performance...</p>
  
  <p>The bottleneck is the <code>bmp.Assign(jpg);</code></p>
  
  <pre><code>function CompareImages(fnFrom, fnTo: TFileName): Boolean;
  var
    j1, j2: TJpegImage;
    b1, b2: TBitmap;
    s1, s2: TMemoryStream;
  begin
    Result := False;
  sw1.Start;
    j1 := TJpegImage.Create;
    j2 := TJpegImage.Create;
  sw1.Stop;
  sw2.Start;
    s1 := TMemoryStream.Create;
    s2 := TMemoryStream.Create;
  sw2.Stop;
  //sw3.Start;
    b1 := TBitmap.Create;
    b2 := TBitmap.Create;
  //sw3.Stop;
    try
    sw1.Start;
      j1.LoadFromFile(fnFrom);
      j2.LoadFromFile(fnTo);
    sw1.Stop;
  
              // the very long part...
              sw3.Start;
                b1.Assign(j1);
                b2.Assign(j2);
              sw3.Stop;
  
  
    sw4.Start;
      b1.SaveToStream(s1);
      b2.SaveToStream(s2);
    sw4.Stop;
    sw2.Start;
      s1.Position := 0;
      s2.Position := 0;
    sw2.Stop;
    sw5.Start;
      Result := IsIdenticalStreams(s1, s2);
    sw5.Stop;
    finally
  //  sw3.Start;
      b1.Free;
      b2.Free;
  //  sw3.Stop;
    sw2.Start;
      s1.Free;
      s2.Free;
    sw2.Stop;
    sw1.Start;
      j1.Free;
      j2.Free;
    sw1.Stop;
    end;
  end;
  </code></pre>
  
  <p>sw1, ..., sw5 are <a href="http://docwiki.embarcadero.com/Libraries/en/System.Diagnostics.TStopwatch" rel="nofollow noreferrer">TStopWatch</a>, I used to identify the time spent.</p>
  
  <p>IsIdenticalStreams comes from <a href="https://stackoverflow.com/a/4606388/596852">here</a>.</p>
  
  <p>If I directly compare the <code>TJpegImage</code>, the streams are different...</p>
  
  <p>Any better way to code that?</p>
  
  <p>Regards,</p>
  
  <p>W.</p>
  
  <p><strong>Update:</strong></p>
  
  <p>Testing some solutions extract from the comments, I have the same performance with this code:</p>
  
  <pre><code>type
    TMyJpeg = class(TJPEGImage)
      public
        function Equals(Graphic: TGraphic): Boolean; override;
    end;
  
  ...
  
  function CompareImages(fnFrom, fnTo: TFileName): Boolean;
  var
    j1, j2: TMyJpeg;
  begin
    sw1.Start;
    Result := False;
    j1 := TMyJpeg.Create;
    j2 := TMyJpeg.Create;
    try
      j1.LoadFromFile(fnFrom);
      j2.LoadFromFile(fnTo);
    Result := j1.Bitmap.Equals(j2.Bitmap);
    finally
      j1.Free;
      j2.Free;
    end;
    sw1.Stop;
  end;
  </code></pre>
  
  <p>Any way to directly access the pixel data bytes from the file (skipping the metadata bytes) without bitmap conversion?</p>