我有两个图像(A和B),想知道图像的矩形交叉点。图像表示滚动的屏幕内容,我只想要没有交叉点的图像的独占值。所以A代表一个捕获,然后B代表相同的屏幕区域,但滚动了一些%的内容,底部有额外的内容。但因为滚动并不总是代表整个内容卷(例如,最后)
所以基本上如果B只是内容的部分滚动视图,我想减少B,因此它不包含A中存在的任何图像数据;因此,当我合并A和B(以及A之前的任何其他卷轴)时,它们不包含重复数据。
这是我将A和B拼接在一起的示例图像;如你所见,内容是重复的。
答案 0 :(得分:1)
这里有一些含糊之处,因为可能有多个交叉点。我的意思是可能有一个像素高的交叉点以及一个100像素的高交叉点。解决这种模糊性的一种方法是在两个图像之间采用最大的交叉点。这是一种蛮力方法。我假设这两个屏幕截图具有相同的维度w
x h
。
Compare each of `h` rows of A to B.
Perform the same comparison on `h-1` rows with A's y coordinates offset by +1 (down 1).
Perform the same comparison on `h-2` rows with A's y coordinates offset by +2 (down 2).
...
每当比较成功时,返回该偏移量。这是A的Y坐标,应该缝在B的顶部。
这里的主要问题是表现。最糟糕的情况是非常糟糕(宽度*高度*高度),但如果每个像素的比较相同,直到最后一个像素为每行。只要一个像素不匹配就通过早期返回,性能可能实际上足够好。
这是一种从给定的Y偏移开始比较图像的简单快捷的方法。
[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int memcmp(IntPtr b1, IntPtr b2, long count);
static bool compareIntersection(int width, int height, int yOffset, IntPtr a, IntPtr b)
{
int bytesPerPixel = 4; // this needs to be set to reflect your image format
int bytesToRead = (height - yOffset) * width * bytesPerPixel;
IntPtr aStart = a + yOffset * width * bytesPerPixel;
return 0 == memcmp(aStart, b, bytesToRead);
}
函数的参数是图像的宽度,图像的高度,A中的y偏移以及指向每个位图内存开头的指针。您可以使用Bitmap.LockBits然后使用BitmapData.Scan0来获取这些指针。
代码未经测试,因此可能会出现问题。