2009-08-29 11 views

答えて

16

あなたはTMemoryStreamに両方のビットマップを保存してCompareMemを使用して比較することができます:

function IsSameBitmap(Bitmap1, Bitmap2: TBitmap): Boolean; 
var 
Stream1, Stream2: TMemoryStream; 
begin 
    Assert((Bitmap1 <> nil) and (Bitmap2 <> nil), 'Params can''t be nil'); 
    Result:= False; 
    if (Bitmap1.Height <> Bitmap2.Height) or (Bitmap1.Width <> Bitmap2.Width) then 
    Exit; 
    Stream1:= TMemoryStream.Create; 
    try 
    Bitmap1.SaveToStream(Stream1); 
    Stream2:= TMemoryStream.Create; 
    try 
     Bitmap2.SaveToStream(Stream2); 
     if Stream1.Size = Stream2.Size Then 
     Result:= CompareMem(Stream1.Memory, Stream2.Memory, Stream1.Size); 
    finally 
     Stream2.Free; 
    end; 
    finally 
    Stream1.Free; 
    end; 
end; 

begin 
    if IsSameBitmap(MyImage1.Picture.Bitmap, MyImage2.Picture.Bitmap) then 
    begin 
    // your code for same bitmap 
    end; 
end; 

私はこのコードXの走査線ベンチマークなかった、あなたがしなければ、私たちは最速となる1お知らせください。

+2

いくつかのコメント:1)コードは例外セーフではありません。 2)ビットマップの幅または高さが異なる場合、私はすぐにFalseを返します。あるいは、ピクセル形式が異なっていても、質問があまりにも漠然としています。 – mghie

+0

いいコメントmghie。コードを変更して、高さと幅をテストします。 –

+0

例外を呑み込むことは、私が意味するものではなく、コードを編集できるようになりました... – mghie

0

正確な回答が必要な場合は、いいえ。近似が必要な場合は、おそらくピクセルの選択をチェックすることができます。しかし、2つのビットマップが完全に同じかどうかを調べるには、ピクセルとピクセル形式のデータ全体を比較する必要があります。

11

TMemoryStreamを使用しないScanLineの使用。

function IsSameBitmapUsingScanLine(Bitmap1, Bitmap2: TBitmap): Boolean; 
var 
i   : Integer; 
ScanBytes : Integer; 
begin 
    Result:= (Bitmap1<>nil) and (Bitmap2<>nil); 
    if not Result then exit; 
    Result:=(bitmap1.Width=bitmap2.Width) and (bitmap1.Height=bitmap2.Height) and (bitmap1.PixelFormat=bitmap2.PixelFormat) ; 

    if not Result then exit; 

    ScanBytes := Abs(Integer(Bitmap1.Scanline[1]) - Integer(Bitmap1.Scanline[0])); 
    for i:=0 to Bitmap1.Height-1 do 
    Begin 
    Result:=CompareMem(Bitmap1.ScanLine[i],Bitmap2.ScanLine[i],ScanBytes); 
    if not Result then exit; 
    End; 

end; 

Bye。

+0

+1非常にうまく構成されています。これの速度とCesarの解を比較することは興味深いでしょう。これはより多くの比較をしますが、メモリを割り当てないことで時間を節約します。結局のところ、質問タイトルは**最速**を指定しました。 – Argalatyr

+1

@RRUZ:同じビットマップが同じメモリレイアウト+1を意味する場合、これは良い解決策であると私は同意します。私は、より興味深い問題である可能性が異なるフォーマットで等しいビットマップの高速チェックを検討したいと思います。 pf24bitまたはpf32bitビットマップの色が256色未満の場合は、pf8bitで保存するのが理にかなっていますが、同じビットマップは引き続き表示されます。 – mghie

+0

私は通常、pf8bitのみを使用していますが、これは問題ありません。あなたはpf12bitと奇数の幅を持っている場合、整列ビットがチェックされても私は思います。 bppが8歳未満の人と同じですが、それらはafaikに計画されています。 –