C 混合文本,由FreeType以颜色和alpha渲染
我正在使用FreeType渲染一些文本 我想在其中绘制文本的表面是一个格式为ARGB、预乘alpha的位图图像 文本所需的颜色也是ARGB 渲染的FT_位图具有格式FT_PIXEL_MODE_LCD-文本在黑色背景上以白色渲染,并具有亚像素抗锯齿 因此,对于每个像素,我有3个数字:C 混合文本,由FreeType以颜色和alpha渲染,c,image-processing,language-agnostic,alpha,freetype,C,Image Processing,Language Agnostic,Alpha,Freetype,我正在使用FreeType渲染一些文本 我想在其中绘制文本的表面是一个格式为ARGB、预乘alpha的位图图像 文本所需的颜色也是ARGB 渲染的FT_位图具有格式FT_PIXEL_MODE_LCD-文本在黑色背景上以白色渲染,并具有亚像素抗锯齿 因此,对于每个像素,我有3个数字: Da、Dr、Dg、Db-目标像素ARGB(背景图像) Fr、Fg、Fb-FreeType渲染像素(使用FT_渲染模式_LCD渲染的FT_位图) Ca、Cr、Cg、Cb-我要使用的文本颜色 所以,问题是:如何正确地组合
Da、Dr、Dg、Db
-目标像素ARGB(背景图像)
Fr、Fg、Fb
-FreeType渲染像素(使用FT_渲染模式_LCD渲染的FT_位图)
Ca、Cr、Cg、Cb
-我要使用的文本颜色
所以,问题是:如何正确地组合这3个数字,以获得位图像素的结果
理论答案还可以,甚至比代码示例更好。将FreeType数据设置为目标文本颜色的强度,而不是实际RGB颜色(这些“原始”值用于绘制黑色文本) 因此,每个
F
颜色分量的全部强度为F*C/255
。但是,由于您的C
还包括一个alpha分量,因此强度由它来缩放:
s' = F*C*A/(255 * 255)
当然,假设F
、C
和A
在通常的0..255范围内A
是一个分数A/255
,第二部分是将F*C
带回到目标范围<代码>s'现在是派生的源颜色
继续策划。对于每个颜色分量,新颜色被添加到D
,而D
又被源的alpha255-A
(缩放)减弱
这就得到了全额
D' = D*(255-A)/255 + F*C*A/(255 * 255)
等于(向右移动一个值)
对于D
、F
、C
和A
的每个单独通道r、g、b。最后一个,alpha,也需要为每个通道单独计算,因为FreeType输出数据返回此格式
如果计算速度太慢,可以将视觉结果与FreeType的非LCD优化灰度输出进行比较。我怀疑,特别是在“繁忙”(不完全是单色)背景上,额外的计算根本不值得。纯灰度输入的数值优势在于,对于每三组RGB颜色,只需计算一次
a
和1-a
“背景”也有一个alpha通道,但要在“背景”上绘制文本,可以将其视为“未使用”。一般来说,将一个透明项绘制到另一个透明项上不会改变其固有的透明度。经过一些发现,我找到了正确的答案。令人失望 在RGBA格式的透明图像上绘制亚像素渲染图形(包括字体)是不可能的 为了正确渲染此类图形,必须使用支持每种颜色的单独alpha通道的格式
例如,每像素48位:RrGgBg,其中r、g和b分别是红色、绿色和蓝色collor通道的alpha通道。哪个alpha是A?背景(目的地)- Da还是颜色- Ca?这个答案是完全错误的,因为它根本不考虑子像素着色。一个测试是将文本呈现为白色背景上的黑色,而不是FreeType返回的黑色背景上的白色文本。
a
是文本颜色C
的alpha。所有其他三个值F
、C
和D
都是RGB三元组(并且D
不需要更改其alpha)。对于灰度自由类型字符,您可以使用a'=a*F
并从公式中删除F
。@MarkRansom:ouch!FreeType难道不返回简单的强度,并将进一步的着色留给最终用户吗?这种逐通道计算保留了亚像素抗锯齿,不是吗?(但自然按源alpha缩放。)@Jongware D-目标(背景)有alpha通道,需要它以便稍后与其他图像混合。
D' = (D*(255-A) + F*C*A/255)/255