2009-08-29 90 views

回答

16

可以节省位图到内存流和使用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扫描线,如果你这样做,请让我们知道哪一个是最快的。

+2

一些评论:1)代码不是异常安全的。 2)如果位图的宽度或高度不同,我会立即返回False。或者,即使像素格式不同,但问题太模糊不清。 – mghie 2009-08-29 21:35:54

+0

好评mghie。我改变代码来测试高度和宽度。 – 2009-08-29 21:46:27

+0

吞咽异常不是我的意思,让我编辑代码... – mghie 2009-08-29 21:51:14

0

如果你需要一个准确的答案,没有。如果你需要一个近似值,你可能会检查一个像素的选择。但是如果你想知道两个位图是否完全相同,你需要比较整个像素和像素格式的数据。

11

使用ScanLine,无TMemoryStream。

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; 

再见。

+0

+1非常好地组成。比较这个与Cesar的解决方案的速度会很有趣。这有更多的比较,但通过不分配内存节省时间。问题标题确实指定了**最快的**,毕竟。 – Argalatyr 2009-08-30 01:45:00

+1

@RRUZ:我同意这是一个很好的解决方案,如果相同的位图意味着相同的内存布局+1。尽管如此,我认为尽快检查可能不同格式的相同位图是一个更有趣的问题。如果pf24bit或pf32bit位图的颜色少于256色,则将其保存为pf8bit是合理的,但仍会显示相同的位图。 – mghie 2009-08-30 06:46:26

+0

我通常只使用pf8bit,为此可以。我想知道如果对齐位被检查,如果你有pf12bit和一个奇数的宽度。 bpp的8以下同样,但是这些都是计划的afaik。 – 2009-08-30 09:28:58