GDI 中文本的透明度

发布于 2024-08-03 22:10:14 字数 109 浏览 4 评论 0原文

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

i have created a Bitmap using GDI+.I am drawing text on to that bitmap using GDI Drawtext.Using Drawtext i am unable to apply tranparency.
Any help or code will be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

巾帼英雄 2024-08-10 22:10:14

如果要绘制没有背景填充的文本,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 的 alpha 设置为 50% 就足够了,并确保 BKColor 为黑色。我不知道 DrawText 会对 Alpha 通道做什么。需要进行一些实验。

If you want to draw text without a background fill, SetBkMode(hdc,TRANSPARENT) will tell GDI to leave the background when drawing text.


To actually render the foreground color of the text with alpha... is going to be more complicated. GDI does not actually support alpha channels all that widely in its APIs. Outside of AlphaBlend actually all it does is preserve the channel. Its actually not valid to set the upper bits of a COLOREF to alpha values as the high byte is actually used for flags to indicate whether the COLOREF is (rather than an RGB value) a palette entry.

So, unfortunately, your only real way forward is to:

  1. Create a 32bit DIBSection. (CreateDIBSection). This gives you an HBITMAP that is guaranteed to be able to hold alpha information. If you create a bitmap via one of the other bitmap creation functions its going to be at the device colordepth that might not be 32bpp.
  2. DrawText onto the DIBSection.
  3. When you created the DIBSection you got a pointer to the actual memory. At this point you need to go through the memory and set the alpha values. I don't think that DrawText is going to do anything to the alpha channel by itself at all. Im thinking a simple check of the RGB components of each DWORD of the bitmap - if theyre the forground color, rewrite the DWORD with a 50% (or whatever) alpha in the alpha byte, if theyre the background color, rewrite with a 100% alpha in the alpha byte. *
  4. AlphaBlend the bitmap onto the final destination. AlphaBlend requires the alpha channel in the source to be pre-multiplied.

*
It might be sufficient to simply memset the DIBSection with a 50% alpha before doing the DrawText, and ensure that the BKColor is black. I don't know what DrawText might do to the alpha channel though. Some experimentation is called for.

柳若烟 2024-08-10 22:10:14

简单而简单的解决方案:)

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

  1. 将场景(位图、图形等)组成
  2. BitBlt 所需的来自该场景的矩形(与您的文本矩形相同,从您想要文本的位置)到内存 DC,并在以下位置选择兼容的位图0,0 目标坐标
  3. 将文本绘制到内存 DC 中的矩形。
  4. 现在,将 BLENDFUNCTION 中没有 AC_SRC_ALPHA 的矩形进行 AlphaBlend,并使用所需的 SourceConstantAlpha 从该内存 DC 返回到场景 DC。

我想你明白了:)

SIMPLE and EASY solution:)

Had this problem, i tried to change alpha values and premultiply, but there was another problem - antialiased and cleartype fonts where not shown correctly (ugly edges). So what i did...

  1. Compose your scene (bitmaps, graphics, etc.)
  2. BitBlt required rectangle from this scene (same as your text rectangle, from the place where you want your text to be) to memory DC with compatible bitmap selected at 0,0 destination coordinates
  3. Draw Your text to that rectangle in memory DC.
  4. Now AlphaBlend that rectangle without AC_SRC_ALPHA in the BLENDFUNCTION and with desired SourceConstantAlpha from this memory DC back to your scene DC.

I think You got it :)

や三分注定 2024-08-10 22:10:14

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

如果它确实不改变 alpha 通道,那么您可能会为两个位图标头指定不同的掩码。一个在适当的位置指定 thr RGB,另一个使它们都将其位分配给 Alpha 通道。 (在本例中将文本颜色设置为白色)然后分两次渲染,一次加载颜色值,另一次加载 Alpha 值。

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

Hmmmm - trying to do same here - wondering - I see that when you create a dib section youi specify the "masks" that is a R,G,B (and alpha) mask.

IF and thats a big if it really does not alter the alpha chhannel, then you might specify the mask differently for two bitmap headers. ONe specifies thr RGB in the proper places, the other makes them all have their bits assigned to the alpha channel. (set the text color to white in this case) then render in two passes, one to load the color values, the other to load the alpha values.

???? anyway just musing :)

飘然心甜 2024-08-10 22:10:14

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

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

看看另一个问题 ...因为在另一个问题中我发布了一些代码你可以很容易地修改......这几乎正是克里斯·贝克在他的回答中所建议的。

While this question is about making text semi-transparent, I had the opposite problem.

DrawText was making the text in my layered window (UpdateLayeredWindow) semi-transparent ... and I didn't want it to be.

Take a look at this other question ... since in the other question I post some code that you could easily modify ... and is almost exactly what Chris Becke suggests in his answer.

蓦然回首 2024-08-10 22:10:14

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

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

A limited answer for a specific situation:

If you have a graphic with alpha channel and you want to draw opaque text over a locally opaque background, first prepare your 32 bit bitmap with 32 bit brushes created with CreateDIBPatternBrushPt. Then scan through the bitmap bits inverting the alpha channel, draw your text as you normally would (including SetBkMode to TRANSPARENT), then invert the alpha in the bitmap again. You can skip the first inversion if you invert the alpha of your brushes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文