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

时间:2011-07-29 04:32:33

标签: c# image-processing bitwise-operators

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

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

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

最快的方法是什么?

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

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

4 个答案:

答案 0 :(得分:0)

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

http://pastebin.com/KXavA9Jr

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

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];
    }
}

实际上这将会更加复杂 - 你的背景可能比你掩盖它的任何前景图像都要大,你必须做一些算术来正确地放置它。虽然很难做到正确,但这并不难。

答案 3 :(得分:0)

我可能误解了这个问题,但是:你有两个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]); 
}

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