【问题标题】:How do I change the glow color of text drawn using DrawThemeTextEx?如何更改使用 DrawThemeTextEx 绘制的文本的发光颜色?
【发布时间】:2013-06-12 14:45:49
【问题描述】:

DrawThemeTextEx 是绘制 Windows Vista 和 7 的 Aero 文本的 API,即带有发光光晕的文本。

要更改使用DrawThemeTextEx 绘制时使用的文本颜色,设置DTTOPTS 结构的crText 字段并在dwFlags 字段中指定DTT_TEXTCOLOR,以指示crText 字段包含有效值。但是文字后面的模糊发光效果总是画白色。设置shadow or border colours 和适当的标志对发光颜色没有影响。 DTTOPTS 结构中的发光颜色没有明显的设置。

您可以在此处看到自定义文本颜色(红色),但它仍然在文本后面呈现白色模糊光晕。比如说,我想用黑色发光代替,因为对于浅色文本,它会使文本更易于阅读。

你如何改变这个白色光晕/辉光的颜色?例如,是否存在具有影响的Dwm* API 或未记录的标志?

【问题讨论】:

  • 不是答案,但您可以创建自定义窗口框架,然后在其中绘制。在这种情况下,您将能够根据需要显示您的文本。详情见MSDN
  • 据我了解,Yahoo Messenger 已经实现了相同的方法:screenshot
  • 谢谢@AshtonHearts,但我不明白这是如何解决问题的。创建自定义窗口框架如何更改使用 DrawThemeTextEx 绘制的文本的背景发光颜色?据我所知,它总是白色的。您的屏幕截图实际上根本没有显示任何带有发光背景的文本 - 也许您指的是他们在标题栏上绘制的徽标?
  • 正如我所说,这不是解决方案。屏幕截图是为了演示自定义字体的使用。如果您的目标是简单地绘制特定样式的文本,那么您可以创建具有发光效果的自定义字体并在自定义窗口框架内绘制文本。
  • 谢谢,但我知道如何使用特定字体和发光效果绘制文本。有关 API 详细信息的链接,请参阅我的问题。我的问题是改变发光颜色,就像你可以改变文本颜色一样。

标签: winapi aero aero-glass


【解决方案1】:

简短的回答是,您不能使用DrawThemeTextEx API:它只允许您更改文本颜色,而不是背景发光颜色。

长答案是您可以通过以下方式达到相同的效果:

  • 用发光绘制文本;
  • 使用 alpha 作为颜色强度对生成的图像进行着色,以获得文本加上发光的单色图像;
  • 在没有发光效果的顶部绘制文本。

显示技术结果的示例图像

第二步,给图像上色,是需要解释的主要步骤。

在临时位图上绘制带有发光的黑色文本。然后,您将拥有一个具有白色和黑色的区域(白色是 Windows 呈现的唯一发光颜色)、不同的 alpha 以及在文本边缘的黑色和白色之间的抗锯齿像素(由于使用的算法)可能是略微着色,即不是纯灰色。

在彩色背景上绘制的发光文本,因此您可以看到白光和文本抗锯齿

有两种选择。第一种是使用颜色(“白色”与“黑色”)和色调将白色区域更改为背景颜色,将黑色区域更改为文本颜色。这将起作用,但与 Windows 呈现和抗锯齿的文本相比,可能会产生抗锯齿错误,尤其是彩色文本。更好的方法是意识到文本将被覆盖,并消除锯齿,背景发光:将所有内容(发光和文本)着色为一种颜色 - 无论是 100% alpha 文本都可以被视为 100% 白色发光下面text - 然后简单地将文本再次绘制到背景上。

然后着色就很简单了。像素将具有 alpha 值和 premultiplied alpha colour 值 - 例如,(2, 2, 2, 2) 的 ABGR 是 2 的 alpha,而白色的 BGR 是预乘 alpha。忽略现有颜色并根据像素的现有 Alpha 将任何非零 Alpha 像素设置为背景颜色的预乘 Alpha 值。

使用TQuadColor struct to represent four bytes of an alpha-aware 32-bit pixel,循环访问您的临时位图并使用现有的 alpha 作为强度设置颜色:

// PQuad is a pointer to the first pixel, a TQuadColor (see link, basically a packed struct of ABGR bytes)
for Loop := 0 to FWidth * FHeight - 1 do begin
  if PQuad.Alpha <> 0 then begin
    PQuad.SetFromColorMultAlpha(Color); // Sets the colour, and multiplies the alphas together
  end;
  Inc(PQuad);
end;

密钥是PQuad.SetFromColorMultAlpha:

procedure TQuadColor.SetFromColorMultAlpha(const Color: TQuadColor);
var
  MultAlpha : Byte;
begin
  Red := Color.Red;
  Green := Color.Green;
  Blue := Color.Blue;
  MultAlpha := Round(Integer(Alpha) * Integer(Color.Alpha) / 255.0);
  SetAlpha(MultAlpha, MultAlpha / 255.0);
end;

这采用四边形颜色(即 RGB 与 alpha)并将两个 alpha 相乘以得到结果 alpha。 这让您可以用透明颜色着色。 SetAlpha 然后转换为预乘 alpha:

procedure TQuadColor.SetAlpha(const Transparency: Byte; const PreMult: Single);
begin
  Alpha := Transparency;
  Blue := Trunc(Blue * PreMult);
  Green := Trunc(Green * PreMult);
  Red := Trunc(Red * PreMult);
end;

结果是有色光晕:

在顶部绘制文本(使用same API 保持相同的文本渲染)不发光:

并且您的文本带有彩色的非白色发光颜色。

您可以在我的MPL-licensed TTransparentCanvas project Google Code 上找到完整的源代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2012-12-26
    • 2023-03-30
    • 2019-08-24
    相关资源
    最近更新 更多