Transparency to text in GDI

独自空忆成欢 提交于 2019-11-29 02:13:42

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.

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 :)

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 :)

cplotts

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.

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!