透明位图上的抗锯齿文本

发布于 2024-08-01 23:13:25 字数 857 浏览 5 评论 0原文

我想在透明位图上绘制抗锯齿文本,并将抗锯齿绘制为 Alpha 混合像素。 这样,我可以将位图绘制到任何颜色表面(或图像)上,并且抗锯齿效果看起来仍然很好。

这是显示问题的简化示例:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    Bitmap bitmap = new Bitmap(this.Width, this.Height);
    Graphics g = Graphics.FromImage(bitmap);
    g.Clear(Color.Empty);
    g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));
    e.Graphics.DrawImage(bitmap, new Point(0, 0));
}

这是结果:

替代文字

这样做的最终目标是使用 UpdateLayeredWindow 绘制透明的 alpha 混合窗口。 我正在创建一个类似 Conky 的应用程序,并且我希望能够使用 ClearType 渲染文本(当然,这很容易,无需抗锯齿)。

目前,我抓住表单后面的屏幕,绘制它,然后绘制我的文本。 看起来不错,但是需要更新,而且画起来很慢。 任何其他在桌面上完成绘制文本的想法也将受到欢迎。

I'd like to draw antialiased text on a transparent bitmap and have the antialiasing drawn as alpha blended pixels. This way, I can draw the bitmap onto any color surface (or an image, for that matter) and the antialiasing still looks fine.

Here is a simplified sample showing the problem:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    Bitmap bitmap = new Bitmap(this.Width, this.Height);
    Graphics g = Graphics.FromImage(bitmap);
    g.Clear(Color.Empty);
    g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));
    e.Graphics.DrawImage(bitmap, new Point(0, 0));
}

And here is the result:

alt text

The ultimate goal of this is to use UpdateLayeredWindow to draw my transparent alpha blended window. I am creating a Conky-like application, and I'd like to be able to use ClearType rendering for text (this is easy without antialiasing, of course).

Currently, I grab the screen behind the form, draw that, and then draw my text. It looks good, but has to be updated and is slow to draw. Any other ideas to accomplish drawing text on the desktop would also be welcome.

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

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

发布评论

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

评论(2

旧梦荧光笔 2024-08-08 23:13:25

您的文本按原样显示是因为您启用了 ClearType 子像素抗锯齿模式(这是 Vista 及更高版本的默认设置)。 根据定义,ClearType 无法与 Alpha 通道很好地配合,因为它混合颜色,因此与背景无关。 因此它会忽略 Alpha 通道,并混合为黑色(否则就是透明颜色)。 您需要启用纯灰度抗锯齿以获得所需的效果:

g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

Your text is displayed as it is because you have ClearType subpixel anti-aliasing mode enabled (which is the default on Vista and above). ClearType, by definintion, cannot play nice with alpha channel, since it blends colors, and thus isn't background-agnostic. So it ignores the alpha channel, and blends to black (which is your transparent color otherwise is). You need to enable plain grayscale anti-aliasing for the desired effect:

g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
半城柳色半声笛 2024-08-08 23:13:25

我不确定这是否真的有必要,但如果你想进行 alpha 混合,你应该指定一个 32 位图像:

Bitmap bitmap = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

使用你的示例,我能够通过添加文本渲染提示使文本看起来不错:

g.Clear(Color.Empty);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));

是这是做你想做的事,还是只是隐藏问题?

I'm not sure if it's really necessary, but if you want to do alpha-blending, you should specify a 32-bit image:

Bitmap bitmap = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

Using your example, I was able to make the text look decent by adding a text rendering hint:

g.Clear(Color.Empty);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));

Is this doing what you want, or just hiding the problem?

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