像素与透明度叠加
Pixels Overlay With transparency
我有 2 个像素B8G8R8A8 (32( 格式。 两个像素(顶部和底部(都具有透明度(Alpha通道<255(
在底部像素上叠加顶部像素的方法(公式(是什么? (不使用第三方(。
我试图做这样的事情
struct FColor
{
public:
// Variables.
#if PLATFORM_LITTLE_ENDIAN
#ifdef _MSC_VER
// Win32 x86
union { struct{ uint8 B,G,R,A; }; uint32 AlignmentDummy; };
#else
// Linux x86, etc
uint8 B GCC_ALIGN(4);
uint8 G,R,A;
#endif
#else // PLATFORM_LITTLE_ENDIAN
union { struct{ uint8 A,R,G,B; }; uint32 AlignmentDummy; };
#endif
//...
};
FORCEINLINE FColor AlphaBlendColors(FColor pixel1, FColor pixel2)
{
FColor blendedColor;
//Calculate new Alpha:
uint8 newAlpha = 0;
newAlpha = pixel1.A + pixel2.A * (255 - pixel1.A);
//get FColor as uint32
uint32 colora = pixel1.DWColor();
uint32 colorb = pixel2.DWColor();
uint32 rb1 = ((0x100 - newAlpha) * (colora & 0xFF00FF)) >> 8;
uint32 rb2 = (newAlpha * (colorb & 0xFF00FF)) >> 8;
uint32 g1 = ((0x100 - newAlpha) * (colora & 0x00FF00)) >> 8;
uint32 g2 = (newAlpha * (colorb & 0x00FF00)) >> 8;
blendedColor = FColor(((rb1 | rb2) & 0xFF00FF) + ((g1 | g2) & 0x00FF00));
blendedColor.A = newAlpha;
return blendedColor;
}
但结果远不是我想要的:-(
我寻找了一些 Alpha 混合公式(我从来不明白我将如何计算叠加层的新 alpha(->也许我走错了方向?
编辑:
将newAlpha
更改为newAlpha = FMath::Min(pixel1.A + pixel2.A, 255);
实际上给出了更好的结果,但是这样计算是否正确?我在这里错过了什么吗?
基于已接受答案的工作示例(
FORCEINLINE FColor AlphaBlendColors(FColor BottomPixel, FColor TopPixel)
{
FColor blendedColor;
//Calculate new Alpha:
float normA1 = 0.003921568627451f * (TopPixel.A);
float normA2 = 0.003921568627451f * (BottomPixel.A);
uint8 newAlpha = (uint8)((normA1 + normA2 * (1.0f - normA1)) * 255.0f);
if (newAlpha == 0)
{
return FColor(0,0,0,0);
}
//Going By Straight Alpha formula
float dstCoef = normA2 * (1.0f - normA1);
float multiplier = 255.0f / float(newAlpha);
blendedColor.R = (uint8)((TopPixel.R * normA1 + BottomPixel.R * dstCoef) * multiplier);
blendedColor.G = (uint8)((TopPixel.G * normA1 + BottomPixel.G * dstCoef) * multiplier);
blendedColor.B = (uint8)((TopPixel.B * normA1 + BottomPixel.B * dstCoef) * multiplier);
blendedColor.A = newAlpha;
return blendedColor;
}
首先假设下面有第三个像素恰好是不透明的。
对于进一步的表示法,我将假设 alpha 值在 [0,1] 中。
给定:三个像素,第一个像素在顶部,颜色c_1、c_2、c_3、alpha 值a_1、a_2、a_3 = 1
那么得到的 alpha 值显然是 1,颜色是
(a_1)*c_1 + (1-a_1)(*a_2)*c_2 + (1-a_1)*(1-a_2)*c_3
现在,我们想c_k找到一些值,a_k以便上面的公式等于
(a_k)*c_k + (1-a_k)*c_3
我们可以通过两个步骤解决这个问题:
(1-a_k) = (1-a_1)*(1-a_2)
->
a_k = 1-(1-a_1)*(1-a_2)
和
(a_k)*c_k = (a_1)*c_1 + (1-a_1)(*a_2)*c_2
->
c_k = [(a_1)*c_1 + (1-a_1)(*a_2)*c_2] / a_k
使用这些公式(alpha值的范围不同(,您将获得所需的颜色。
(不要忘记抓住a_k = 0(
编辑:第三个像素的解释:
当您以任何方式使用两个像素时,即执行导致其用于显示某些内容的操作,它们将被置于其他不透明的现有颜色上。例如,这可能是背景色,但也可能是在某些背景色上应用更多透明像素的结果。
我现在要做的是将你的两种颜色结合起来,找到一种表现得和这两种颜色一样的颜色。也就是说,将其放在某种不透明颜色的顶部应该与将原始的两种颜色放在其顶部的结果相同。这就是我对新颜色的要求,导致我使用的公式。
该公式只不过是在第三种颜色上连续应用两种颜色的结果。
- 将位图 (bmp) 转换为具有透明度的 png (Windows c++)
- Vulkan是否需要在多个具有透明度的平局调用之间进行同步
- 像素与透明度叠加
- 如何从透明度计算不透明度?
- 杀戮计数器滞后游戏的透明叠加层
- 如何创建和分发 SteamVR 仪表板叠加层
- GEOS叠加相交操作
- 在 openFrameworks 上设置图像的透明度
- 暂停游戏OnSteamVR叠加层处于活动状态
- 使用大理石的自定义地图叠加
- glcolor4f-绘制时无法获得完全不透明度
- 视差图和校正图像之间的叠加
- VTK抽象选择器,用于不同不透明度值的多个参与者
- 动态添加叠加微件
- 叠加多个小部件
- 在openFrameworks中,是否可以在使用ofxPiMapper时更改我的fbo源的不透明度
- 打开简历,视频叠加
- 如何使用GDI 显示具有25%不透明度的PNG图像?(MFC)
- QT非阻滞叠加对话框
- Gstreamer 文本叠加未更新