簡體   English   中英

在GDI +中沿其筆划寬度繪制具有線性漸變的折線

[英]Draw a polyline with a linear gradient along it's stroke width in GDI+

是否可以繪制沿筆划寬度具有線性漸變的折線? 也就是說,如果您的漸變為0和100%為黑色,白色為50%,則無論角度如何,黑色始終位於線條的邊緣,白色始終位於中間。 可以將其視為某種3D管道。 當然,該行的筆划寬度至少為10px。 這里的所有問題都詢問如何在兩端之間填充一條線。 我對此絕對不感興趣。 我正在使用GDI +在C#中工作,可以是任何.NET版本。

我想這就是你想要的:

截圖

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

Screenshot2

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

截圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM