我正在尝试使用TextRenderer
绘制一些文字(因为这有利于Graphics.DrawString
}使用Bitmap
,但它会产生一些非常不良影响。
示例代码
using (Bitmap buffer = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
using (Graphics graphics = Graphics.FromImage(buffer))
{
// Produces the result below
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
// Produces clean text, but I'd really like ClearType!
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
TextRenderer.DrawText(graphics, "Hello World", this.Font, this.ClientRectangle, Color.Black);
}
e.Graphics.DrawImageUnscaled(buffer, this.ClientRectangle);
}
结果
我不确定如何解决这个问题......帮助!
我不想使用Graphics.DrawString
因为我想要正确的GDI(而不是GDI +)渲染。
注意:我刚刚意识到,我在这个问题上留下了一个漏洞。有些人指出,渲染ClearType文本在他们的机器上工作正常......
我正在尝试将文本渲染为透明(Color.Transparent)位图。如果我用纯色做,一切正常! (但我必须渲染到透明的位图)。
答案 0 :(得分:4)
您可以尝试为TextRenderingHint
设置Image Graphics
:
using (Graphics graphics = Graphics.FromImage(buffer))
{
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
TextRenderer.DrawText(graphics, "Hello World", this.Font, this.ClientRectangle, Color.Black);
}
答案 1 :(得分:3)
问题是TextRenderer使用GDI渲染使用ClearType来渲染文本,clear-type使用特殊的抗锯齿算法来平滑文本,不幸的是当你尝试在位图设备上绘图时它不起作用
要使其工作,你必须使用技巧,绘制到内存中,然后复制到位图:
有关详细信息,请参阅此博客:GDI text rendering to image。
示例代码,抱歉有点长:
public static class Test
{
public static Image Render()
{
// create the final image to render into
var image = new Bitmap(190, 30, PixelFormat.Format32bppArgb);
// create memory buffer from desktop handle that supports alpha channel
IntPtr dib;
var memoryHdc = CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib);
try
{
// create memory buffer graphics to use for HTML rendering
using (var memoryGraphics = Graphics.FromHdc(memoryHdc))
{
// must not be transparent background
memoryGraphics.Clear(Color.White);
// execute GDI text rendering
TextRenderer.DrawText(memoryGraphics, "Test string 1", new Font("Arial", 12), new Point(5, 5), Color.Red, Color.Wheat);
TextRenderer.DrawText(memoryGraphics, "Test string 2", new Font("Arial", 12), new Point(100, 5), Color.Red);
}
// copy from memory buffer to image
using (var imageGraphics = Graphics.FromImage(image))
{
var imgHdc = imageGraphics.GetHdc();
BitBlt(imgHdc, 0, 0, image.Width, image.Height, memoryHdc, 0, 0, 0x00CC0020);
imageGraphics.ReleaseHdc(imgHdc);
}
}
finally
{
// release memory buffer
DeleteObject(dib);
DeleteDC(memoryHdc);
}
return image;
}
private static IntPtr CreateMemoryHdc(IntPtr hdc, int width, int height, out IntPtr dib)
{
// Create a memory DC so we can work off-screen
IntPtr memoryHdc = CreateCompatibleDC(hdc);
SetBkMode(memoryHdc, 1);
// Create a device-independent bitmap and select it into our DC
var info = new BitMapInfo();
info.biSize = Marshal.SizeOf(info);
info.biWidth = width;
info.biHeight = -height;
info.biPlanes = 1;
info.biBitCount = 32;
info.biCompression = 0; // BI_RGB
IntPtr ppvBits;
dib = CreateDIBSection(hdc, ref info, 0, out ppvBits, IntPtr.Zero, 0);
SelectObject(memoryHdc, dib);
return memoryHdc;
}
[DllImport("gdi32.dll")]
public static extern int SetBkMode(IntPtr hdc, int mode);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref BitMapInfo pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
[DllImport("gdi32.dll")]
public static extern int SelectObject(IntPtr hdc, IntPtr hgdiObj);
[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern bool DeleteDC(IntPtr hdc);
[StructLayout(LayoutKind.Sequential)]
internal struct BitMapInfo
{
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
public byte bmiColors_rgbBlue;
public byte bmiColors_rgbGreen;
public byte bmiColors_rgbRed;
public byte bmiColors_rgbReserved;
}
}
答案 2 :(得分:2)
在对DrawText()的调用中指定BackColor:
TextRenderer.DrawText(graphics, "Hello World", this.Font, this.ClientRectangle, Color.Black, this.BackColor);