在调用GDI文本函数后如何修复alpha值?

我有一个使用Aero玻璃效果的应用程序,因此除红色,绿色和蓝色值外,每个像素都有一个alpha值。 我有一个自定义绘制控件,具有纯白色背景(alpha = 255)。 我想使用GDI文本函数在控件上绘制纯文本。 但是,这些函数将alpha值设置为任意值,导致文本半透明地显示我的应用程序下面的任何窗口。

在调用渲染文本之后,我想通过控件中的所有像素并将其alpha值设置回255.这样做的最佳方法是什么?

我对BitBltGetPixelSetPixel函数没有任何好运。 他们似乎忘记了阿尔法值。

以下是我考虑和拒绝的其他解决方案:

  • 绘制到位图,然后将位图复制到设备:使用此方法,文本渲染不会使用监视器的特征(例如,ClearText)。 如果您知道一种方法可以让GDI将文本渲染到位图, 就像渲染到屏幕一样,这也可以解决我的问题。
  • 使用GDI +进行文本呈现:此应用程序最初使用GDI +进行文本呈现(在我开始使用Aero支持之前)。 由于我在尝试使用GDI +精确测量字符串时遇到困难,我切换到GDI。 我宁愿不回头。
  • 设置Aero区域以避免相关控件:我的应用程序窗口实际上是在不同进程中运行的不同应用程序的子窗口。 我无法直接控制顶级窗口上的Aero设置。

该应用程序是使用Windows Forms以C#编写的,尽管我上面没有使用Interop来调用Win32 API函数。

以下是我最终提出的解决方案。 它有点难看,可能会被简化,但它确实有效。 我们的想法是基于原始的Graphics对象(即屏幕)创建一个BufferedGraphics对象。 在BufferedGraphics对象中,TextRenderer.DrawText()将呈现文本,就像它绘制到屏幕时一样。 然后我创建一个常规图形对象,将Buffered Graphics对象复制到常规图形对象,最后将常规图形对象绘制到屏幕上。

 Rectangle inner = new Rectangle(Point.Empty, ContentRectangle.Size); using (BufferedGraphics bg = BufferedGraphicsManager.Current.Allocate(e.Graphics, inner)) { using (Bitmap bmp = new Bitmap(inner.Width, inner.Height, bg.Graphics)) { using (Graphics bmpg = Graphics.FromImage(bmp)) { bg.Graphics.Clear(BackColor); do_my_drawing(bg.Graphics); bg.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; bmpg.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; bg.Render(bmpg); e.Graphics.DrawImageUnscaledAndClipped(bmp, ContentRectangle); } } } 

设置所有CompositingMode属性可能不是必需的,但是一旦我开始工作,我就不会费心测试所有的排列,以确定需要哪些(如果有的话)。

您可能想尝试在单独的位图上使用GDI +,将其复制到屏幕上。 优点是用GDI +绘制的文本的alpha将显示位图的颜色(你将其涂成白色),而不是使位图透明化。

但实际上,GDI +有很多错误或只是不准确的文本测量function。 但也许你可以使用GDI函数 。 最后,您的GDI +文本渲染应该与您现在拥有的GDI文本渲染完全一样,因此可能值得一试。