人们,我确信这很容易,但谷歌没有帮助......
这是任务 - 我有两个字节数组(作为ARGB),代表我的图像。它们的大小相同。 我应该执行什么操作(逐字节)将一个图像叠加到另一个图像? 第二张图片有一定的透明度,必须加以考虑。
要清除,我正在寻找这样的代码:
bytes[] result = new bytes[first.Length];
for(i = 0; i< first.Lenght;i++)
{
result[i] = first[i] !!%SOMETHING%!! second[i];
}
简单的猜测,如按位OR(我知道 - 那是愚蠢的;))不起作用。
谢谢你的答案。
编辑:由于安全问题,我无法使用标准库(所有这些奇怪的操作都发生在Silverlight上)。
答案 0 :(得分:7)
假设您实际上正在使用位图,您可能会发现让图书馆为您执行此操作更容易。
System.Drawing.Graphics
类有一个CompositingMode
属性,可以设置为SourceCopy
(默认值 - 覆盖背景颜色)或SourceOver
(与背景颜色混合) )。
有关详细信息,请参阅MSDN: How to Use Compositing Mode to Control Alpha Blending。
如果你只想要原始数学,alpha混合非常简单。对于介于0.0和1.0之间的alpha值 a ,结果应为:
(aOld * oldValue) + ((1 - aOld) * aNew * newValue)
其中oldValue
是叠加前的前一个值,newValue
是您要叠加的内容,aOld
和aNew
分别是旧的和新的Alpha值。你显然需要分别对R,G和B值进行计算。
另请参阅:Alpha Compositing(wiki链接)以获得更全面的解释。
更新:我认为应该很容易弄清楚如何使其适应OP中的代码,但我想不是每个人都是数学家。
我将假设byte[]
是A,R,G,B值的重复序列(因此Length
将是4的倍数)。如果情况并非如此,那么您必须将此代码调整为您正在使用的任何存储格式。
bytes[] result = new bytes[first.Length];
for(i = 0; i < first.Length; i += 4)
{
byte a1 = first[i];
byte a2 = second[i];
byte r1 = first[i+1];
byte r2 = second[i+1];
byte g1 = first[i+2];
byte g2 = second[i+2];
byte b1 = first[i+3];
byte b2 = second[i+3];
byte a = a1 + (255 - a1) * a2 / 255;
byte r = r1 * a1 / 255 + r2 * (255 - a1) * a2 / 65025;
byte g = g1 * a1 / 255 + g2 * (255 - a1) * a2 / 65025;
byte b = b1 * a1 / 255 + b2 * (255 - a1) * a2 / 65025;
result[i] = a;
result[i+1] = r;
result[i+2] = g;
result[i+3] = b;
}
答案 1 :(得分:0)
我认为你有正确的想法。您使用的操作取决于您对输出的要求。以下是一些有用的操作:
您可以添加或者透明度字节,并对三种颜色中的每一种使用其他操作之一。