【问题标题】:Transparency to text in GDIGDI 中文本的透明度
【发布时间】:2010-11-23 08:00:54
【问题描述】:

我已经使用 GDI+创建了一个位图。我正在使用 GDI Drawtext 在该位图上绘制文本。使用 Drawtext 我无法应用透明度。 任何帮助或代码将不胜感激。

【问题讨论】:

  • 首选语言? C、C++、VB.net、C#??
  • 首选纯 Windows API / C++

标签: winapi gdi


【解决方案1】:

如果您想绘制没有背景填充的文本,SetBkMode(hdc,TRANSPARENT) 将告诉 GDI 在绘制文本时离开背景。


要实际使用 alpha 渲染文本的前景色...将会更加复杂。 GDI 实际上并没有在其 API 中广泛支持 alpha 通道。在AlphaBlend 之外,实际上它所做的只是保留频道。将 COLOREF 的高位设置为 alpha 值实际上是无效的,因为高字节实际上用于指示 COLOREF 是否(而不是 RGB 值)调色板条目。

因此,不幸的是,您唯一真正的前进方向是:

  1. 创建一个 32 位 DIBSection。 (CreateDIBSection)。这为您提供了一个保证能够保存 alpha 信息的 HBITMAP。如果您通过其他位图创建函数之一创建位图,则其设备颜色深度可能不是 32bpp。
  2. 在 DIBSection 上绘制文本。
  3. 当您创建 DIBSection 时,您会得到一个指向实际内存的指针。此时您需要遍历内存并设置 alpha 值。我认为 DrawText 根本不会对 alpha 通道做任何事情。我正在考虑对位图的每个 DWORD 的 RGB 分量进行简单检查 - 如果它们是前景色,则用 alpha 字节中的 50%(或其他)alpha 重写 DWORD,如果它们是背景色,则用 100% 重写alpha 字节中的 alpha。 *
  4. AlphaBlend 位图到最终目的地。 AlphaBlend 要求对源中的 Alpha 通道进行预乘。

* 在执行 DrawText 之前简单地将 DIBSection 设置为 50% alpha 并确保 BKColor 为黑色可能就足够了。我不知道 DrawText 可能会对 alpha 通道做什么。需要进行一些实验。

【讨论】:

  • 感谢您的回复。我已使用此方法。使用此方法可将文本透明地绘制到矩形上。但我想将透明度(alpha)应用于使用 SetTextColor 方法无法绘制的文本.由于 SetTextColor 忽略了颜色的 alpha 值。我已经完成了一些使用掩码位图来应用透明度的应用程序,但我没有得到想要的结果。而且我不想对位图应用透明度,我想对绘制在位图上的文本应用透明度。任何帮助表示赞赏
  • 这个想法是,在黑色位图上绘制,而不是在上面有信息的位图上绘制。对文本进行位图处理后,您可以扫描位图以查找非黑色像素,并根据每个像素是否属于文本部分来调整每个像素的 Alpha 通道。
【解决方案2】:

简单易行的解决方案:)

遇到这个问题,我尝试更改 alpha 值并进行预乘,但还有另一个问题 - 抗锯齿和 cleartype 字体未正确显示(丑陋的边缘)。所以我做了什么......

  1. 组合您的场景(位图、图形等)
  2. BitBlt 需要从该场景(与您的文本矩形相同,从您希望文本所在的位置)到内存 DC 的矩形,在 0,0 目标坐标处选择兼容位图
  3. 将文本绘制到内存 DC 中的那个矩形。
  4. 现在 AlphaBlend 将 BLENDFUNCTION 中没有 AC_SRC_ALPHA 的矩形和所需的 SourceConstantAlpha 从这个内存 DC 中返回到场景 DC。

我想你明白了:)

【讨论】:

    【解决方案3】:

    嗯 - 在这里尝试做同样的事情 - 想知道 - 我看到当你创建一个 dib 部分时,你指定了作为 R、G、B(和 alpha)掩码的“掩码”。

    如果它确实不改变 alpha 通道,那是一个很大的问题,那么您可以为两个位图标题指定不同的掩码。一个在适当的位置指定 thr RGB,另一个使它们都将它们的位分配给 alpha 通道。 (在这种情况下将文本颜色设置为白色)然后分两次渲染,一次加载颜色值,另一次加载 alpha 值。

    ????无论如何只是在沉思:)

    【讨论】:

      【解决方案4】:

      虽然这个问题是关于使文本半透明的,但我遇到了相反的问题。

      DrawText 使我的分层窗口 (UpdateLayeredWindow) 中的文本半透明......我不希望它是。

      看看另一个question ...因为在另一个问题中我发布了一些您可以轻松修改的代码...这几乎正是 Chris Becke 在他的回答中所建议的。

      【讨论】:

        【解决方案5】:

        针对特定情况的有限答案:

        如果您有一个带有 Alpha 通道的图形,并且您想在局部不透明的背景上绘制不透明的文本,请首先准备您的 32 位位图和使用CreateDIBPatternBrushPt 创建的 32 位画笔。然后扫描反转 alpha 通道的位图位,像往常一样绘制文本(包括 SetBkModeTRANSPARENT),然后再次反转位图中的 alpha。如果您反转画笔的 alpha,则可以跳过第一次反转。

        【讨论】:

          猜你喜欢
          • 2015-05-04
          • 2017-07-02
          • 2022-08-11
          • 2012-03-27
          • 2014-03-12
          • 2013-03-04
          • 1970-01-01
          • 2011-01-25
          • 2016-09-17
          相关资源
          最近更新 更多