我正在寻找一种算法来执行RGB颜色值的加法混合。
是否只需要将RGB值相加,最大值为256?
(r1, g1, b1) + (r2, g2, b2) =
(min(r1+r2, 256), min(g1+g2, 256), min(b1+b2, 256))
我正在寻找一种算法来执行RGB颜色值的加法混合。
是否只需要将RGB值相加,最大值为256?
(r1, g1, b1) + (r2, g2, b2) =
(min(r1+r2, 256), min(g1+g2, 256), min(b1+b2, 256))
t
)。我相信我的实现仍然是“累加”的。这种方法在我的所有测试用例中都能很好地混合。在这里,new_argb
只是将 int
转换为一个具有 4 个 unsigned char
的结构体,以便我可以减少位移量。int blend_argb(int foreground, int background)
{
t_argb fg;
t_argb bg;
t_argb blend;
double ratio;
fg = new_argb(foreground);
bg = new_argb(background);
// If background is transparent,
// use foreground color as-is and vice versa.
if (bg.a == 255)
return (foreground);
if (fg.a == 255)
return (background);
// If the background is fully opaque,
// ignore the foreground alpha. (Or the color will be darker.)
// Otherwise alpha is additive.
blend.a = ((bg.a == 0) ? 0 : (bg.a + fg.a));
// When foreground alpha == 0, totally covers background color.
ratio = fg.a / 255.0;
blend.r = (fg.r * (1 - ratio)) + (bg.r * ratio);
blend.g = (fg.g * (1 - ratio)) + (bg.g * ratio);
blend.b = (fg.b * (1 - ratio)) + (bg.b * ratio);
return (blend.a << 24 | blend.r << 16 | blend.g << 8 | blend.b);
}
为了提供上下文,我正在将颜色int
写入1D像素数组中,该数组使用0字节进行初始化,并增加alpha值将使像素趋向于黑色。(0
0 0 0
将是不透明的黑色,255
255 255 255
将是透明的白色...也就是黑色。)
这是一个高度优化的、独立的C++类,公共领域,具有浮点数和两种不同优化的8位混合机制,分别以函数和宏格式呈现,以及对问题本身、如何进行优化以及优化此问题的重要性的技术讨论:
感谢Markus Jarderot、Andras Zoltan和hkurabko;这里是混合RGB图像列表的Python代码。
使用Markus Jarderot的代码,我们可以生成RGBA颜色,然后我使用Andras Zoltan和hkurabko的方法将RGBA转换为RGB。
谢谢!
import numpy as np
def Blend2Color(C1,C2):
c1,c1a=C1
c2,c2a=C2
A = 1 - (1 - c1a) * (1 - c2a);
if (A < 1.0e-6):
return (0,0,0) #Fully transparent -- R,G,B not important
Result=(np.array(c1)*c1a+np.array(c2)*c2a*(1-c1a))/A
return Result,A
def RGBA2RGB(RGBA,BackGround=(1,1,1)):# whilt background
A=RGBA[-1]
RGB=np.add(np.multiply(np.array(RGBA[:-1]),A),
np.multiply(np.array(BackGround),1-A))
return RGB
def BlendRGBList(Clist,AlphaList=None,NFloat=2,ReturnRGB=True,
RGB_BackGround=(1,1,1)):
N=len(Clist)
if AlphaList==None:
ClistUse=Clist.copy()
else:
if len(AlphaList)==N:
AlphaListUse=np.multiply(AlphaList,10**NFloat).astype(int)
ClistUse=np.repeat(np.array(Clist), AlphaListUse, axis=0)
else:
raise('len of AlphaList must equal to len of Clist!')
while N!=1:
temp=ClistUse.copy()
ClistUse=[]
for C in temp[:-1]:
c1,a1=C
c2,a2=temp[-1]
ClistUse.append(Blend2Color(C1=(c1,a1*(1-1/N)),C2=(c2,a2*1/N)))
N=len(ClistUse)
Result=np.append(ClistUse[0][0],ClistUse[0][1])
if ReturnRGB:
Result=RGBA2RGB(Result,BackGround=RGB_BackGround)
return Result
测试
BlendRGBList([[(1,0,0),1],[(0,1,0),1]],ReturnRGB=True)
#array([0.75, 0.5 , 0.25])
BlendRGBList([[(1,0,0),1],[(0,1,0),1]],ReturnRGB=False)
#array([0.66666667, 0.33333333, 0. , 0.75 ])