【问题标题】:Draw a polyline with a linear gradient along it's stroke width in GDI+在 GDI+ 中沿其笔划宽度绘制具有线性渐变的折线
【发布时间】:2012-09-13 12:35:32
【问题描述】:

是否可以绘制一条沿其笔触宽度具有线性渐变的折线?也就是说,如果您有一个渐变,黑色为 0 和 100%,白色为 50%,无论角度如何,黑色将始终位于线条边缘,白色位于中间。将其视为某种 3D 管道。当然,线条的笔触宽度至少为 10px。这里的所有问题都询问如何在两端之间填充一条线。我绝对对此不感兴趣。我正在使用 GDI+ 在 C# 中工作,可以是任何 .NET 版本。

【问题讨论】:

    标签: c# .net graphics gdi+ gradient


    【解决方案1】:

    我想这就是你想要的:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode=SmoothingMode.AntiAlias;
    
            DrawPipe(e.Graphics, 10f, new PointF(10, 10), new PointF(250, 80), Color.White, Color.Black);
    
            DrawPipe(e.Graphics, 10f, new PointF(15, 60), new PointF(280, 120), Color.BlueViolet, Color.Black);
        }
    
        private void DrawPipe(Graphics g, float width, PointF p1, PointF p2, Color mid_color, Color edge_color)
        {
            SizeF along=new SizeF(p2.X-p1.X, p2.Y-p1.Y);
            float mag=(float)Math.Sqrt(along.Width*along.Width+along.Height*along.Height);
            along=new SizeF(along.Width/mag, along.Height/mag);
            SizeF perp=new SizeF(-along.Height, along.Width);
    
            PointF p1L=new PointF(p1.X+width/2*perp.Width, p1.Y+width/2*perp.Height);
            PointF p1R=new PointF(p1.X-width/2*perp.Width, p1.Y-width/2*perp.Height);
            PointF p2L=new PointF(p2.X+width/2*perp.Width, p2.Y+width/2*perp.Height);
            PointF p2R=new PointF(p2.X-width/2*perp.Width, p2.Y-width/2*perp.Height);
    
            GraphicsPath gp=new GraphicsPath();
            gp.AddLines(new PointF[] { p1L, p2L, p2R, p1R});
            gp.CloseFigure();
    
            Region region=new Region(gp);
            using(LinearGradientBrush brush=new LinearGradientBrush(
                p1L, p1R, Color.Black, Color.Black))
            {                
                ColorBlend color_blend=new ColorBlend();
                color_blend.Colors=new Color[] { edge_color, mid_color, edge_color };
                color_blend.Positions=new float[] { 0f, 0.5f, 1f };
                brush.InterpolationColors=color_blend;
                g.FillRegion(brush, region);
            }
        }
    }
    

    编辑 1

    另一种方法是使用PathGradientBrush

    GraphicsPath gp = new GraphicsPath();
    gp.AddLines(new PointF[] { p1, p1L, p2L, p2, p2R, p1R });
    gp.CloseFigure();
    
    Region region = new Region(gp);
    using (PathGradientBrush brush = new PathGradientBrush(gp))
    {
        brush.CenterColor = mid_color;
        brush.SurroundColors = new Color[] 
        {
            mid_color, edge_color,edge_color,mid_color,edge_color,edge_color
        };          
        g.FillRegion(brush, region);
    }
    

    编辑 2

    要使边缘更平滑,请使用一些 alpha 透明度:

    using(LinearGradientBrush brush=new LinearGradientBrush(
        p1L, p1R, Color.Black, Color.Black))
    {
        ColorBlend color_blend=new ColorBlend();
        color_blend.Colors=new Color[] { 
            Color.FromArgb(0, edge_color), edge_color, mid_color, 
            edge_color, Color.FromArgb(0, edge_color) };
        color_blend.Positions=new float[] { 0f, 0.1f, 0.5f, 0.9f, 1f };
        brush.InterpolationColors=color_blend;
        g.FillRegion(brush, region);
    }
    

    编辑 3 对于一些工件,正在绘制多条线,方法是先在线条之间渲染圆圈,然后再绘制线条

        private void DrawPipes(Graphics g, float width, PointF[] points, Color mid_color, Color edge_color)
        {
            for (int i = 0; i < points.Length; i++)
            {
                using (GraphicsPath gp = new GraphicsPath())
                {
                    gp.AddEllipse(points[i].X - width / 2, points[i].Y - width / 2, width, width);
    
                    using (PathGradientBrush brush = new PathGradientBrush(gp))
                    {
                        brush.CenterColor = mid_color;
                        brush.SurroundColors = new Color[] { edge_color };
                        brush.CenterPoint = points[i];
                        g.FillPath(brush, gp);
                    }
                }
                if (i > 0)
                {
                    DrawPipe(g, width, points[i - 1], points[i], mid_color, edge_color);
                }
            }
        }
    

    【讨论】:

    • 这正是我需要的!我现在很累要检查它,但我明天会做。但我还有一个问题:你能把它应用到折线上吗?我相信在渐变应该以某种方式弯曲的角落做它不会很好。无论如何,这是一个很好的答案,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2015-09-24
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多