比较屏幕截图并获取第一个像素变化的屏幕坐标

比较屏幕截图并获取第一个像素变化的屏幕坐标

本文介绍了比较屏幕截图并获取第一个像素变化的屏幕坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个截屏,相隔几秒钟。我正在比较这两个图像,并试图找出它们之间是否有任何差异。如果存在差异,我需要获取该像素变化的屏幕坐标。

I have two screenshots taken one after another with a few seconds gap. I am comparing both the images and trying to find out if there are any differences between them. If there are any differences, i need to get the screen coordinates of that pixel change.

我可以使用Delphi来实现吗?

Can I achieve this using Delphi?

推荐答案

如果要比较两个位图,并且需要找到第一个不同像素的位置,则可以迭代位图行,获取每一行的位图像素数组比较两个位图,如果不匹配,则找到另一个像素的水平位置。在代码中,它可能看起来像这样:

If you have two bitmaps to compare and you need to find a position of the first different pixel, you can iterate the bitmap rows, get the bitmap pixel array for each row of both bitmaps, compare them and if they don't match, find the horizontal position of a different pixel. In code it might look like this:

function CompareBitmaps(ABitmap1, ABitmap2: TBitmap;
  var ADiffPixel: TPoint): Boolean;
var
  X, Y: Integer;
  Size: Integer;
  Pixels1, Pixels2: PByteArray;
begin
  // first check if both bitmaps match in size and pixel format
  Result := (ABitmap1.PixelFormat = ABitmap2.PixelFormat) and
    (ABitmap1.Width = ABitmap2.Width) and (ABitmap1.Height = ABitmap2.Height);
  // if so, then...
  if Result then
  begin
    // assign the size of one pixel
    case ABitmap1.PixelFormat of
      pf24bit: Size := SizeOf(TRGBTriple);
      pf32bit: Size := SizeOf(TRGBQuad);
    else
      raise Exception.Create('Bitmap must be 24-bit or 32-bit format!');
    end;
    // iterate all the bitmap rows
    for Y := 0 to ABitmap1.Height - 1 do
    begin
      // get pointer to pixel data array of the same row for both bitmaps
      Pixels1 := ABitmap1.ScanLine[Y];
      Pixels2 := ABitmap2.ScanLine[Y];
      // compare those pixel data arrays; if they differ, then...
      if not CompareMem(Pixels1, Pixels2, ABitmap1.Width * Size) then
      begin
        // return negative result
        Result := False;
        // assign vertical pixel position to the output ADiffPixel parameter
        ADiffPixel.Y := Y;
        // iterate the current row to find a different pixel; after it's found
        // the pixel's horizontal position is stored to the output ADiffPixel
        // parameter; the pixel array is treated as a byte array, so there's
        // need to be a division by the pixel size
        for X := 0 to ABitmap1.Width * Size - 1 do
          if (Pixels1[X] <> Pixels2[X]) then
          begin
            ADiffPixel.X := X div Size;
            Exit;
          end;
      end;
    end;
  end
  else
    raise Exception.Create('Bitmaps must match in size and pixel format!');
end;

示例用法:

procedure TForm1.Button1Click(Sender: TObject);
var
  PixelPos: TPoint;
begin
  if CompareBitmaps(Image1.Picture.Bitmap, Image2.Picture.Bitmap, PixelPos) then
    ShowMessage('Bitmaps are the same!')
  else
    ShowMessage('Bitmaps are different! The first different pixel was found ' +
      'at [' + IntToStr(PixelPos.X) + '; ' + IntToStr(PixelPos.Y) + '].');
end;

这篇关于比较屏幕截图并获取第一个像素变化的屏幕坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 21:50