人们,我确信这很容易,但谷歌没有帮助……
这是任务 – 我有两个字节数组(作为ARGB),代表我的图像.它们具有相同的尺寸.
我应该执行什么操作(逐字节)将一个图像叠加到另一个图像?
第二张图像具有一定的透明度,必须予以考虑.
要清除,我正在寻找这样的代码:
bytes[] result = new bytes[first.Length]; for(i = 0; i< first.Lenght;i++) { result[i] = first[i] !!%sOMETHING%!! second[i]; }
简单的猜测,如按位OR(我知道 – 这是愚蠢的;))不起作用.
谢谢你的回答.
编辑:我不能使用标准库因为安全问题(所有这些奇怪的操作都发生在Silverlight上).
解决方法
假设您实际上正在使用位图,您可能会发现让库为您执行此操作更容易.
system.drawing.graphics类具有CompositingMode属性,可以将其设置为Sourcecopy(默认值 – 覆盖背景颜色)或SourceOver(与背景颜色混合).
有关详细信息,请参见MSDN: How to Use Compositing Mode to Control Alpha Blending.
如果你只想要原始数学,alpha混合非常简单.对于介于0.0和1.0之间的alpha值,结果应为:
(aOld * oldValue) + ((1 - aOld) * aNew * newValue)
其中oldValue是overlay之前的前一个值,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; }