问题描述
我有两个截屏,相隔几秒钟。我正在比较这两个图像,并试图找出它们之间是否有任何差异。如果存在差异,我需要获取该像素变化的屏幕坐标。
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;
这篇关于比较屏幕截图并获取第一个像素变化的屏幕坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!