How to draw a subpixel line

前端 未结 5 2641
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-19 22:27

In the following code, I\'m trying to draw two lines: One with a subpixel width (0.5) and the other with 1px width:

        var img = new Bitmap(256, 256);
              


        
5条回答
  •  别跟我提以往
    2021-02-19 23:12

    Subpixel lines can be drawn as thin rectangles.
    Here's how to do this:

        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);
            }
        }
    

    Example:

        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);
            }
        }
    

    Result of example:

提交回复
热议问题