我正在使用Graphics.DrawString()
在透明背景的位图上绘制字符串,当字体大小小于23毫米(字体是使用GraphicsUnit.Millimeter
创建的)时,我得到了黑色轮廓的文本。
编码:
Bitmap bmp = new Bitmap(2000, 2000);
Color alpha = Color.FromArgb(0, 0, 0, 0);
for (int x = 0; x < bmp.Width; x++)
for (int y = 0; y < bmp.Height; y++)
bmp.SetPixel(x, y, alpha);
Graphics g = Graphics.FromImage(bmp);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
Font labelFont = new Font("Cascadia Mono SemiBold", 23/*22*/, FontStyle.Regular, GraphicsUnit.Millimeter);
Brush brush = new SolidBrush(Color.White);
g.DrawString("Some text", labelFont, brush, 200, 200);
23毫米-单位字体:
22毫米-单位字体:
我尝试使用TextRenderer
,但它绘制的文本没有透明背景。
1条答案
按热度按时间rslzwgfq1#
此处提供的代码存在多个问题:
Color.FromArb(0, 0, 0, 0)
)SetPixel()
方法,这是执行此任务的最慢的工具using
语句声明的(这是非常糟糕的)。位图何时被释放还不清楚,但可能是使用它的代码的职责若要指定Fonts的呈现模式,则使用TextRenderingHint属性。由于未指定该属性,因此使用Font的系统默认平滑,通常为ClearType。
关于此渲染形式,请参见中的注解:
Drawing a Long String on to a Bitmap results in Drawing Issues
ClearType使用像素内平滑(最初是为LCD屏幕设计的)将文本与背景混合;它对小字体特别有效。它不支持alpha颜色(至少在这里不支持)。
呈现文本的设备上下文(GDI+ MemoryBitmap)不使用或 * 理解 * 这种类型的提示(平滑),因此无法呈现的像素将填充为空颜色,通常显示为黑色
当ClearType提示填充小于一个像素时,带黑色的 * 轮廓 * 可能显示不同的字体大小(不仅仅是问题中报告的度量)
若要修复呈现,请删除混乱,指定合适的
TextRenderingHint
模式并正确声明所有可处置对象。我没有包括位图,因为我不知道它是如何使用的。当然,它必须在某个时候被处置(非常重要,它分配非托管资源,垃圾收集器无法帮助您)
TextRenderingHint.AntiAliasGridFit
在这里是合适的(另请参见链接的注解),字符是使用其反锯齿字形位图和提示(平滑)绘制的TextRenderingHint.AntiAlias
也可用于此上下文中(并且 * 成本 * 略低)CompositingQuality.HighQuality
在这里实际上并没有使用,因为没有在背景上渲染图像(这可能需要gamma校正),所以实际上没有任何合成,但也没有 cost。您可以保留它,以防您决定在某个时候在当前上绘制位图;或者简单地将其移除。关于 *TextRenderer绘制不带透明背景的文本 *
这是不正确的。TextRenderer(GDI)当然可以呈现具有透明背景的文本,只是它不支持alpha颜色(在此上下文中)
如前所述,我们使用的是内存中的**GDI+**设备上下文
但是,如果您在不同的设备上下文(例如,控件的表面)中绘制相同的文本,则情况会发生变化。
另请注意,TextRenderer不能用于在打印时呈现文本(原因与上述相同)。
测试此代码,订阅PictureBox的Paint事件,同时添加背景图像(如果没有背景图像,结果不会更改,只是更明显)
Graphics.DrawString()
用于使用半透明(ARGB)颜色渲染文本导致(放大):