Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 121. - Porovnání dvou bitmap

Jan Šindelář - 17.12.2003

Porovnání dvou bitmap

Porovnání dvou bitmap můžeme udělat poměrně snadno pomocí dvou komponent Image. Předpokládáme, že oba obrázky mají stejné rozměry a pak není žádný problém projít obrázky pixel po pixelu a kontrolovat rozdíly. Cílem tedy není zjistit, zda jsou obrázky totožné (i když pochopitelně i tento fakt lze uvedeným postupem ověřit), protože to bychom mohli udělat daleko efektivnějším způsobem (prostým porovnáním CRC souborů a podobně), ale spíše nás zajímá, do jaké míry se oba obrázky budou lišit. Proto budeme procházet obrázky bod po bodu a výstupem naší funkce pak bude počet rozdílů. Sami si pak můžete vypočítat, na kolik procent jsou obrázky stejné. Pokud je počet rozdílných pixelů vzhledem k jejich celkovému počtu malý, dají se obrázky prohlásit za stejné.

Na formulář tedy umístíme pouze dvě komponenty Image a jedno tlačítko. Do komponent načteme porovnávané obrázky (opět připomínám, že bitmapy musí mít stejné rozlišení, případně tento stav musíte ošetřit v programu) a nebo obrázky načteme za běhu aplikace. Jako událost tlačítka pak napíšeme naši porovnávací proceduru, jejímž výstupem bude počet nalezených rozdílů.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var x, y, d: integer;
begin
  d := 0;
  for x := 0 to Image1.Picture.Bitmap.Height - 1 do
    for y := 0 to Image1.Picture.Bitmap.Width - 1 do
      if Image1.Picture.Bitmap.Canvas.Pixels[x, y] <> Image2.Picture.Bitmap.Canvas.Pixels[x, y] then Inc(d);
  ShowMessage(`Pocet rozdilu: ` + IntToStr(d));
end;

end.

Problém ovšem nastává, pokud jsou sice obrázky totožné, ale jeden z nich obsahuje například nějaký efekt (zesvětlení, barevná clona). Lidské oko na první pohled vidí, že se jedná o stejnou fotografii a rozdíl je jen v odstínu, program ovšem porovnává body podle barev a obrázky prohlásí za odlišné. V tom případě bychom mohli funkci vylepšit tak, že bychom si vypočítali rozdíl v barvě pixelů a pokud bude tento rozdíl konstantní pro celý obrázek (tj. druhý obrázek bude například celý zesvětlen či ztmaven), dá se hovořit rovněž o stejných obrázcích. Tento problém už ale nechám na vašem uvážení.