开发者

C#自定义画刷原理解析

开发者 https://www.devze.com 2022-12-01 14:12 出处:网络 作者: 林子xxx
windows系统中的画板工具,有好几种画刷,C#中并没有直接对应可使用的类,只能自己研究。1.画刷原理根据本人对PS的相关功能细心分析,发现各种画刷其实就是一幅图片的移位重叠显示。通常这幅画刷图是半...

Windows系统中的画板工具,有好几种画刷,C#中并没有直接对应可使用的类,只能自己研究。

1.画刷原理

根据本人对PS的相关功能细心分析,发现各种画刷其实就是一幅图片的移位重叠显示。通常这幅画刷图是半透明的,只有其中一些区域有颜色。

C#自定义画刷原理解析

上图中的画刷,把间隔设大之后可以明显看到原图的模样。

这是基于位移的画刷,另外有基于时间的,比如喷枪工具。

2.代码实现

1).  直线算法

为什么要直线算法?因为我们移动鼠标,触发MouseMove事件,记录鼠标前一坐标点与当前点,如果两点是是相邻的,当然不需要再做多余的算法,当如果两点是不相邻的,我们就需要计算两点之间所有的点。否则无法有效地进行固定间隔绘制画刷图。

/// <summary>
/// 顺序获取两点间直线上的所有点
/// </summary>
/// <para编程客栈m name="pStart">开始点</param>
/// <param name="pEnd">结束点</param>
/// <returns>两点间直线上的所有点</returns>
private List<Point> getPoint2Point(Point pStart, Point pEnd)
    {
      List<Point> linePoint = new List<Point>();
      if (pStart.X js== pEnd.X && pStart.Y == pEnd.Y)
      {
        linePoint.Add(pStart);
        return linePoint;
      }
      DDALine(pStart.X, pStart.Y, pEnd.X, pEnd.Y, ref linePoint);
   编程   return linePoint;
    }
    //DDA直线画法
    private void DDALine(int x0, int y0, int x1, int y1, ref List<Point> ptl)
    { 
      int dx,dy,eps1,k; 
      float x,y,xIncre,yIncre; 
      dx=x1-x0; 
      dy=y1-y0; 
      x=x0; 
      y=y0; 
      if(Math.Abs(dx)>Math.Abs(dy)) 
      eps1=Math.Abs(dx); 
      else 
      eps1=Math.Abs(dy); 
      xIncre=(float)dx/(float)eps1; 
      yIncre=(float)dy/(float)eps1; 
      for(k=0;k<=eps1;k++) 
      {
        ptl.Add( new Point((int)(x + 0.5), (int)(y + 0.5)) ); 
        x+=xIncre; 
        y+=yIncre; 
      } 
    }

2).鼠标事件

分别为鼠标按下、移动、放开事件

bool bIsDraw = false; //主图画线
Point startPoint_Draw = new Point();//划线点变量
List<Point> pts = new List<Point>();//画点保存
private void pictureBox_main_MouseMove(object sender, MouseEventArgs e)
{
      PicturpythoneBox pb = sender as PictureBox;
      ssl_point.Text = e.Location.ToString();
      pb.Refresh();
      if (bIsDraw)
      {
        Point p = limitPoint(e.Location, pictureBox_main.ClientSize);
        if (p == startPoint_Draw) return;
        Graphics gs = Graphics.FromImage(pb.Image);
        if (pictureBox_main.Image != null )
        {
          List<Point> pl = getPoint2Point(startPoint_Draw, p);
          pl.RemoveAt(0);
          pts.AddRange(pl);
          if (pts.Count >= peninv)
          {
            for (int i = penmod; i < pts.Count; i += peninv)
            {
              gs.DrawImage(blushbmp_curr, pts[i].X - pensize , pts[i].Y - pensize , pensize*2, pensize*2);
            }
            penmod = pts.Count % peninv;
            pts.RemoveRange(0, pts.Count - penmod);
          }
     开发者_Python开发   }
        gs.Dispose();
        startPoint_Draw = p;
      }
    }
    private void pictureBox_main_MouseDown(object sender, MouseEventArgs e)
    {
      if(e.Button == System.Windows.Forms.MouseButtons.Left)
      if (bIsDraw == false)
      {
        startPoint_Draw = e.Location;
        pts.Clear();
        pts.Add(startPoint_Draw);
        bIsDraw = true;
      }
    }
    private void pictureBox_main_MouseUp(object spythonender, MouseEventArgs e)
    {
      if (bIsDraw == true)
      {
        bIsDraw = false;
        if (pictureBox_main.Image != null  )
        {
          pts.Clear();
        }
        pictureBox_main.Refresh(); 
      }
    }

如果根据位移方向加上图片的角度旋转效果,应该会更加接近PS的效果。

3.效果

我使用的画刷图就是来源于本文上图的PS画刷。

C#自定义画刷原理解析

图中5条画刷线分别使用间隔1,10,20,40,80。使用不同的原图,就能得到各种各样的画刷。

C#自定义画刷原理解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号