PictureBox中画不规则区域,并更换图片

pshy 2014-09-04 09:45:54
我想在PictureBox中用鼠标画一个不规则区域出来,然后填充一张图片在该区域,以实现么,要怎么整?
在线等,谢谢!
...全文
205 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
pshy 2014-09-05
  • 打赏
  • 举报
回复
谢谢,先试下
Forty2 2014-09-05
  • 打赏
  • 举报
回复
方法之一可以用蒙板,比如Graphics.Clip。 新建一个Winform项目,在Form1.cs下贴入如下代码:
public partial class Form1 : Form
{
    public Form1()
    {
        //InitializeComponent();
        this.Text = "鼠标左键点击选点,右键结束区域选择";
    }

    Bitmap bmp1 = new Bitmap(@"c:\temp\penguins.jpg");//要换成你的图片
    Bitmap bmp2 = new Bitmap(@"c:\temp\Tulips.jpg");  //要换成你的图片
    Region region = null;
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.DrawImage(bmp1, this.ClientRectangle);
        if (region != null)
        {
            e.Graphics.Clip = region;
            e.Graphics.DrawImage(bmp2, this.ClientRectangle);
        }
    }

    List<Point> points = new List<Point>();
    protected override void OnMouseClick(MouseEventArgs e)
    {
        points.Add(e.Location);
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            using(Graphics g = this.CreateGraphics())
            {
                Rectangle rect = Rectangle.Inflate(new Rectangle(points[0], Size.Empty), 2,2);
                g.FillEllipse(Brushes.Red, rect);
                if (points.Count >= 2)
                {
                    g.DrawLines(Pens.Red, points.ToArray());
                }
            }
        }
        else if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            this.region = null;
            if (points.Count >= 3)
            {
                using (GraphicsPath path = new GraphicsPath())
                {
                    path.StartFigure();
                    path.AddLines(this.points.ToArray());
                    path.CloseFigure();
                    this.region = new Region(path);
                }
            }
            this.points.Clear();
            this.Invalidate();
        }
    }
}
正宗熊猫哥 2014-09-05
  • 打赏
  • 举报
回复
3楼好敬业啊
effun 2014-09-05
  • 打赏
  • 举报
回复
写了一段简单的代码供参考。使用前先在窗体中放2个Button、1个PictureBox和1个OpenFileDialog,然后分别关联Button的Click事件和PictureBox的Paint、MouseClick事件到相应的处理程序上。 运行以后,可用鼠标在PictureBox上点击来绘制区域,然后可以用button1用来打开要填充的图片,button2可以清除已绘制的区域。

    public partial class Form1 : Form
    {
        Outline _outline;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                pictureBox1.Image = Image.FromFile(openFileDialog1.FileName);
            }
        }

        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (_outline == null)
                {
                    _outline = new Outline();
                    _outline.Closed += _outline_Closed;
                }
                else if (_outline.IsClosed)
                    return;

                _outline.AddPoint(e.Location);

                pictureBox1.Invalidate();
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (_outline != null)
                    _outline.Close();
            }
        }

        void _outline_Closed(object sender, EventArgs e)
        {
            Outline outline = (Outline)sender;
            GraphicsPath path = new GraphicsPath();
            path.AddPolygon(outline.Points);
            pictureBox1.Region = new System.Drawing.Region(path);
            pictureBox1.Invalidate();

            path.Dispose();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (_outline != null)
            {
                Graphics g = e.Graphics;
                Point[] points = _outline.Points;

                if (!_outline.IsClosed)
                {

                    if (points.Length > 0)
                    {

                        Rectangle clip = e.ClipRectangle;

                        foreach (Point pt in points)
                        {
                            if (clip.Contains(pt))
                            {
                                Rectangle rect = new Rectangle(pt.X - 2, pt.Y - 2, 5, 5);
                                g.DrawRectangle(Pens.Red, rect);
                            }
                        }

                        if (points.Length > 1)
                        {
                            g.DrawLines(Pens.Red, points);
                        }
                    }
                }
                else if (pictureBox1.Image == null)
                {
                    g.FillPolygon(Brushes.Red, points);
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _outline = null;
            pictureBox1.Region = null;
            pictureBox1.Invalidate();
        }

        class Outline
        {
            public event EventHandler Closed;

            List<Point> _points;
            bool _closed;

            public Outline()
            {
                _points = new List<Point>(10);
            }

            public Point[] Points
            {
                get { return _points.ToArray(); }
            }

            public void AddPoint(Point point)
            {
                if (_closed)
                    throw new InvalidOperationException();

                if (_points.Count > 0)
                {
                    Point init = _points[0];
                    Rectangle test = new Rectangle(init.X - 2, init.Y - 2, 5, 5);
                    if (test.Contains(point))
                    {
                        Close();
                        return;
                    }
                }

                _points.Add(point);
            }

            public void AddPoint(int x, int y)
            {
                AddPoint(new Point(x, y));
            }

            public void Close()
            {
                if (!_closed)
                {
                    _closed = true;
                    if (Closed != null)
                        Closed(this, EventArgs.Empty);
                }
            }

            public bool IsClosed
            {
                get { return _closed; }
            }
        }

    }

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧