c# – 预乘alpha合成
我正在尝试实现预乘的alpha混合.在这个页面上:
What Is Color Blending?,它们确实解释了标准的alpha混合,但没有解释预乘的值.
Alpha混合:(来源×Blend.SourceAlpha)(目的地×Blend.InvSourceAlpha) 根据公式,它转换为: a = ((srcA * srcA) >> 8) + ((tgtA * (255 - srcA)) >> 8); r = ((srcR * srcA) >> 8) + ((tgtR * (255 - srcA)) >> 8); g = ((srcG * srcA) >> 8) + ((tgtG * (255 - srcA)) >> 8); b = ((srcB * srcA) >> 8) + ((tgtB * (255 - srcA)) >> 8); 它有效,显然…… 现在我如何将其转换为处理预乘值? a = ((srcA)) + ((tgtA * (255 - srcA)) >> 8); r = ((srcR)) + ((tgtR * (255 - srcA)) >> 8); g = ((srcG)) + ((tgtG * (255 - srcA)) >> 8); b = ((srcB)) + ((tgtB * (255 - srcA)) >> 8); 由于它已被预乘,我在第一项中丢弃乘法……对! 谢谢. 解决方法
预乘的原因是因为在将源图像添加到目标之前,它实际上最终会对目标的alpha进行平方
例如.如果没有预先乘法,我们会得到源图像数据: srcA = origA srcR = origR srcG = origG srcB = origB 当我们应用于目标时,我们会得到这个结果图像: a = ((srcA * srcA) >> 8) + ((tgtA * (255 - srcA)) >> 8) r = ((srcR * srcA) >> 8) + ((tgtR * (255 - srcA)) >> 8) g = ((srcG * srcA) >> 8) + ((tgtG * (255 - srcA)) >> 8) b = ((srcB * srcA) >> 8) + ((tgtB * (255 - srcA)) >> 8) 扩展这个我们得到: a = ((origA * origA) >> 8) + ((tgtA * (255 - origA)) >> 8) r = ((origR * origA) >> 8) + ((tgtR * (255 - origA)) >> 8) g = ((origG * origA) >> 8) + ((tgtG * (255 - origA)) >> 8) b = ((origB * origA) >> 8) + ((tgtB * (255 - origA)) >> 8) 没有惊喜…… 现在,对于预乘的源图像数据,我们得到: srcA = (origA * origA) >> 8 srcR = (origR * origA) >> 8 srcG = (origG * origA) >> 8 srcB = (origB * origA) >> 8 当应用于目标时,它是: a = (srcA >> 8) + ((tgtA * (255 - srcA)) >> 8); r = (srcR >> 8) + ((tgtR * (255 - srcA)) >> 8); g = (srcG >> 8) + ((tgtG * (255 - srcA)) >> 8); b = (srcB >> 8) + ((tgtB * (255 - srcA)) >> 8); 好的,所以我们知道这一点,但是如果我们扩展它,你会看到差异: a = (origA * origA) >> 8 + ((tgtA * (255 – ((origA * origA) >> 8))) >> 8); r = (origR * origA) >> 8 + ((tgtR * (255 - ((origA * origA) >> 8))) >> 8); g = (origG * origA) >> 8 + ((tgtG * (255 – ((origA * origA) >> 8))) >> 8); b = (origB * origA) >> 8 + ((tgtB * (255 – ((origA * origA) >> 8))) >> 8); 将其与NON Pre-Multiplied扩展比较: a = ((origA * origA) >> 8) + ((tgtA * (255 - origA)) >> 8) r = ((origR * origA) >> 8) + ((tgtR * (255 - origA)) >> 8) g = ((origG * origA) >> 8) + ((tgtG * (255 - origA)) >> 8) b = ((origB * origA) >> 8) + ((tgtB * (255 - origA)) >> 8) 然后你可以看到我们正在将origA值应用到目标时对其进行平方,这意味着更多的目标将通过生成的颜色值. 通过对你说,你想要更多的目标来实现. 这就是为什么在预乘时它会消除透明块周围的条带数量,因为具有较低Alpha值的像素获得的目标像素数比未预先相乘的情况多得多,而且这种情况以指数级进行. 我希望这能搞清楚. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |