混合文本,由 FreeType 以颜色和 alpha 渲染

Blending text, rendered by FreeType in color and alpha

我正在使用 FreeType 渲染一些文本。

我要绘制文本的表面是格式为 ARGB、预乘 alpha 的位图图像。

需要的文字颜色也是ARGB。

呈现的 FT_Bitmap 具有格式 FT_PIXEL_MODE_LCD - 这是因为文本在黑色背景上以白色呈现,具有子像素抗锯齿。

所以,对于每个像素,我有 3 个数字:

Da, Dr, Dg, Db - 目标像素 ARGB(背景图像)。

Fr, Fg, Fb - FreeType 渲染像素(FT_Bitmap 用 FT_RENDER_MODE_LCD 渲染)

Ca, Cr, Cg, Cb - 我要使用的文本颜色。

所以,问题是:如何正确组合这 3 个数字以获得结果位图像素。

理论上的答案还可以,甚至比代码示例还要好。

不是将 FreeType 数据解释为实际的 RGB 颜色(这些 'raw' 值用于以黑色绘制文本)而是作为目标文本颜色的 强度

所以每个 F 颜色分量的完整强度是 F*C/255。但是,由于您的 C 还包含一个 alpha 分量,因此强度会按比例缩放:

 s' = F*C*A/(255 * 255)

当然,假设 FCA 在 0..255 的通常范围内。 A是分数A/255,二次除法是把F*C带回目标范围。 s' 现在是 派生的 源颜色。

开始策划。对于每个颜色分量,新颜色会添加到 D,而 D 又会因源的 alpha 255-A(缩放)而变暗。

这导致总和

D' = D*(255-A)/255 + F*C*A/(255 * 255)

等于(向右移动一个值)

D' = (D*(255-A) + F*C*A/255)/255

对于 DFCA 的每个单独通道 r、g、b。最后一个,alpha,也需要对每个通道单独计算,因为你的FreeType输出数据returns这种格式。

如果计算速度太慢,您可以将视觉结果与 FreeType 的非 LCD 优化灰度输出进行比较。我怀疑特别是在 'busy'(不是完全单色)背景上,额外的计算根本不值得。
纯灰度输入的数值优势在于,您只需为每个 RGB 颜色三元组计算一次 A1-A

"background" 也有一个 alpha 通道,但是要绘制文本 "on" 您可以将其视为 'unused'。将透明项目绘制到另一个透明项目上通常不会改变其固有透明度。

经过一番探索,我找到了正确的答案。这是令人失望的。

无法在RGBA格式的透明图片上绘制子像素渲染图形(包括字体)。

为了正确呈现此类图形,必须使用支持每种颜色的单独 Alpha 通道的格式。

例如每像素 48 位:RrGgBg,其中 r、g 和 b 分别是红色、绿色和蓝色颜色通道的 Alpha 通道。