我正在使用 FreeType 渲染一些文本。
我要绘制文本的表面是格式为 ARGB、预乘 alpha 的位图图像。
需要的文字颜色也是ARGB。
呈现的 FT_Bitmap 具有 FT_PIXEL_MODE_LCD 格式 - 这是因为文本在黑色背景上呈现为白色,具有子像素抗锯齿。
所以,对于每个像素,我有 3 个数字:
Da, Dr, Dg, Db
- 目标像素 ARGB(背景图像)。
Fr, Fg, Fb
- FreeType 渲染像素(使用 FT_RENDER_MODE_LCD 渲染的 FT_Bitmap)
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
又被源的 alpha 255-A
(缩放)变暗。
这导致了全额
D' = D*(255-A)/255 + F*C*A/(255 * 255)
等于(向右移动一个值)
D' = (D*(255-A) + F*C*A/255)/255
对于 D
、F
、C
和 A
的每个单独 channel r、g、b。最后一个,alpha,也需要为每个 channel 单独计算,因为您的 FreeType 输出数据返回这种格式。
如果计算速度太慢,您可以将视觉结果与 FreeType 的非 LCD 优化灰度输出进行比较。我怀疑特别是在“繁忙”(不完全是单色)背景下,额外的计算根本不值得。
纯灰度输入的数值优势在于,您只需为 RGB 颜色的每个三元组计算一次 A
和 1-A
。
“背景”也有一个 alpha channel ,但要在“背景”上绘制文本,您可以将其视为“未使用”。将透明项目绘制到另一个透明项目上通常不会改变其固有透明度。
关于c - 混合文本,由 FreeType 以颜色和 alpha 渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33507617/