2012-09-13 163 views
2

是否可以繪製線條漸變沿線條線寬的多段線?也就是說,如果您的黑色漸變顏色爲0和100%,白色爲50%,則無論角度如何,黑色將始終位於線條的邊緣,中間的白色位於中間。把它想象成某種3D管道。當然,該行的筆觸寬度至少爲10px。這裏的所有問題都要求如何在兩端之間填補一條線。我絕對不會對此感興趣。我正在使用GDI +在C#中工作,可以是任何.NET版本。在GDI中用線性漸變繪製線條漸變的折線+

回答

7

我想這是你想要的東西:

Screenshot

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

Screenshot

+0

這正是我需要的!我現在很累,現在看看,但明天我會做。但我還有一個問題:你可以將它應用於多段線嗎?我相信在角落裏做梯度曲線應該不錯。無論如何,這是一個很好的答案,非常感謝! – Tiborg

+0

看看上面的新編輯,多段線。 – ja72