在下面的代码中,我试图绘制两条线:一条具有子像素宽度(0.5),另一条具有1px宽度:
var img = new Bitmap(256, 256);
Graphics graphics = Graphics.FromImage(img);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
// Draw a subpixel line (0.5 width)
graphics.DrawLine(new Pen(Color.Red, (float)0.5), 0, 100, 255, 110);
// Draw a single pixel line (1 width)
graphics.DrawLine(new Pen(Color.Red, (float)1), 0, 110, 255, 120);
img.Save(@"c:\temp\test.png", ImageFormat.Png);
graphics.Dispose();
img.Dispose();
但是,在生成的图像中,两条线的宽度都相同:
顶行是否有办法显示子像素(0.5px)?
答案 0 :(得分:7)
你可以通过绘制所有x2然后缩小它来破解它:
Image img2x = new Bitmap(256*2, 256*2);
Graphics g2x = Graphics.FromImage(img2x);
g2x.SmoothingMode = SmoothingMode.AntiAlias;
g2x.DrawLine(new Pen(Color.Red, 0.5f*2), 0, 100*2, 255*2, 110*2);
Image img = new Bitmap(256, 256);
Graphics g = Graphics.FromImage(img);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawImage(img2x, 0, 0, 256, 256);
g.DrawLine(new Pen(Color.Red, 1f), 0, 110, 255, 120);
img.Save(@"c:\tmep\test.png", ImageFormat.Png);
答案 1 :(得分:2)
子像素线可以绘制为细矩形。
操作方法如下:
public static class GraphicsExtensions
{
public static void DrawLineAnyWidth(this Graphics gr, Pen pen, PointF pt1, PointF pt2)
{
if (pen.Width > 1.5f)
{
gr.DrawLine(pen, pt1, pt2);
}
else
{
var poly = new PointF[5];
var h = pen.Width * 0.5f;
var br = new SolidBrush(pen.Color);
poly[0] = SidePoint(pt1, pt2, -h);
poly[1] = SidePoint(pt1, pt2, h);
poly[2] = SidePoint(pt2, pt1, -h);
poly[3] = SidePoint(pt2, pt1, h);
poly[4] = poly[0];
gr.FillPolygon(br, poly);
br.Dispose();
}
}
static PointF SidePoint(PointF pa, PointF pb, float h)
{
float Dx = pb.X - pa.X;
float Dy = pb.Y - pa.Y;
float D = (float)Math.Sqrt(Dx * Dx + Dy * Dy);
return new PointF(pa.X + Dy * h / D, pa.Y - Dx * h / D);
}
}
示例:
var bmp = new Bitmap(200, 350);
using (var gr = Graphics.FromImage(bmp))
{
gr.Clear(Color.White);
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
var pen = new Pen(Color.IndianRed);
for (int i = 1; i < 30; i++)
{
var pa = new PointF(50, 20 + i * 10);
var pb = new PointF(150, 30 + i * 10);
pen.Width = i * 0.1f;
gr.DrawLineAnyWidth(pen, pa, pb);
}
}
答案 2 :(得分:1)
答案 3 :(得分:0)
在这种情况下,我不认为在这里使用子像素是有意义的。无论如何,您将它导出到图像文件。请尝试更大的宽度值。
答案 4 :(得分:0)
This article提到了GDI + Pen中的一个错误,当它的宽度小于1.5
时,它无法正常缩小。
此外,如果您尝试分别绘制宽度为2.0F
,2.5F
和3.0F
的三条线,您会看到视觉差异,因此您的情况看起来确实存在问题GDI +。