如何利用C#中的掩码数组快速将两个图像byte 数组组合在一起

简而言之,我有两个图像,我想使用一个掩码覆盖另一个,以便只显示第二个图像的一部分。 这是实时图像处理程序的一部分,因此我需要尽可能快地进行操作。

具体来说,我有两个32位图像BGR字节数组。 另外,我有一个表示图像掩码的字节数组。

我想生成一个新的字节数组,其中字节数组A使用掩码数组重叠在字节数组B的顶部,以决定使用哪个字节。

最快的方法是什么?

我正在看这篇关于老式精灵屏蔽的维基百科文章,但我不知道如何最好地将其转换为C#。 http://en.wikipedia.org/wiki/Mask_(computing )

编辑:我忘了提到我可以重新构建任何或所有这些以使其运行得更快。

原则上,这样的掩码非常简单 – 假设数组大小相同,这段代码就可以了:

static void MaskImage(byte[] background, byte[] foreground, byte[] mask) { for (var i = 0; i < background.Length; ++i) { background[i] &= mask[i]; background[i] |= foreground[i]; } } 

实际上,这将变得更加复杂 - 您的背景可能比您屏蔽它的任何前景图像都要大,并且您必须进行一些算术才能正确放置它。 虽然很难做到正确,但并不难。

此代码不适用于单个字节数组,但我处理的项目需要将一个图像覆盖在另一个图像上。 也许这会对你有所帮助。

http://pastebin.com/KXavA9Jr

第三方工具是可行的方法。 我使用过Lead Tools,但还有很多其他的。

如果您想自己动手,可以使用LockBits方法。

LockBits的最佳演示在这里: http : //www.bobpowell.net/lockingbits.htm但链接目前已经死亡。 希望鲍威尔先生能够解决这个问题。

我可能误解了这个问题,但是:你有两个int数组和一个相同大小的掩码aray,它将相应的掩码应用于两个图像数组。 如果掩码数组中的某个位为0,则从A中选择该位; 当为1时,从b中选择位。

因此,例如,如果您在第一个数组元素中有值:

  a[0] : 0000 1111 b[0] : 0011 0011 mask[0] : 0101 0101 

那么目标结果将是:

  dest[i] : 0001 1011 

这可以表示为:

 dest[i] = (a[i] AND (NOT MASK[i])) OR (b[i] AND MASK[i]) 

或者,在C#中:

 dest[i] = (a[i] & ~mask[i]) | (b[i] & mask[i]); 

如果这是意图,那么你可以像循环一样运行:

 for (int i = 0; i < len; i++) { dest[i] = (a[i] & ~mask[i]) | (b[i] & mask[i]); } 

最后,在性能方面,一个注意事项:您提到创建一个新数组来保存目标图像。 如果图像具有相当大的尺寸,则不断创建大型arrays可能成为瓶颈。 相反,如果可能,创建一次目标数组并根据需要重用它。 此外,如果您确实需要分配大量字节数组以供临时使用(例如,在方法中),您可能需要考虑使用stackalloc运算符在堆栈上分配空间,这比创建新的托管数组更有效。