请高手介绍下C# winform 绘图编程

解决方案 »

  1.   

    system.drawing
    gdi+
    熟悉下什么是画笔、画刷、调色板、画布等等概念。
      

  2.   

    使用C#在Windows应用程序里绘图,可能用到移动图像、擦掉图像,调整大小等等。这里有一个画图的小程序,简单的实现了这些(转)定义图像的基类:abstract class DrawBase
    ...{
        internal Color m_BackColor;
        internal Color m_ForeColor;
        internal static int m_HalfGrab;    public static int HalfGrab
        ...{
            get ...{ return DrawBase.m_HalfGrab; }
            set ...{ DrawBase.m_HalfGrab = value; }
        }    public Color BackColor
        ...{
            get ...{ return m_BackColor; }
            set ...{ m_BackColor = value; }
        }    public Color ForeColor
        ...{
            get ...{ return m_ForeColor; }
            set ...{ m_ForeColor = value; }
        }    public abstract Rectangle GetBound();
        public abstract void Draw(Graphics g);
        public abstract bool Near(int x, int y);
        public abstract void SetBound(Rectangle bound);
    }
    定义线:class LineObj:DrawBase
    ...{
        private Point m_Start;
        private Point m_End;
        public LineObj(Point start, Point end)
        ...{
            this.m_Start = start;
            this.m_End = end;
        }
        public override System.Drawing.Rectangle GetBound()
        ...{
            int x = this.m_Start.X < this.m_End.X ? this.m_Start.X : this.m_End.X;
            int y = this.m_Start.Y < this.m_End.Y ? this.m_Start.Y : this.m_End.Y;
            int r = this.m_Start.X < this.m_End.X ? this.m_End.X : this.m_Start.X;
            int b = this.m_Start.Y < this.m_End.Y ? this.m_End.Y : this.m_Start.Y;
            return Rectangle.FromLTRB(x, y, r, b);
        }    public override void Draw(System.Drawing.Graphics g)
        ...{
            using (Pen pen = new Pen(this.m_ForeColor))
            ...{
                g.DrawLine(pen, this.m_Start, this.m_End);
            }
        }    public override bool Near(int x, int y)
        ...{
            //点到直线的距离是否在抓取范围之内
            float A = this.m_End.Y- this.m_Start.Y;
            float B = this.m_End.X- this.m_Start.X;
            float C = B * this.m_Start.Y - A * this.m_Start.X;
            double D = (A * x - B * y + C) / (Math.Sqrt(A * A + B * B));
            if (D >= -m_HalfGrab && D <= m_HalfGrab)
            ...{
                RectangleF bounds = this.GetBound();
                bounds.Inflate(m_HalfGrab, m_HalfGrab);
                return bounds.Contains(x, y);
            }
            return false;
        }    public override void SetBound(Rectangle bound)
        ...{
            this.m_Start = new Point(bound.X, bound.Y);
            this.m_End = new Point(bound.Right, bound.Bottom);
        }
    }
    定义矩形:class RectangleObj:DrawBase
    ...{
        private Point m_Start;
        private Point m_End;
        private bool m_Solid;
        public RectangleObj(Point start, Point end)
        ...{
            this.m_Start = start;
            this.m_End = end;
        }
        public bool Solid
        ...{
            get ...{ return m_Solid; }
            set ...{ m_Solid = value; }
        }
        public override System.Drawing.Rectangle GetBound()
        ...{
            int x = this.m_Start.X < this.m_End.X ? this.m_Start.X : this.m_End.X;
            int y = this.m_Start.Y < this.m_End.Y ? this.m_Start.Y : this.m_End.Y;
            int r = this.m_Start.X < this.m_End.X ? this.m_End.X : this.m_Start.X;
            int b = this.m_Start.Y < this.m_End.Y ? this.m_End.Y : this.m_Start.Y;
            return Rectangle.FromLTRB(x, y, r, b);
        }    public override void Draw(Graphics g)
        ...{
            Rectangle bound = this.GetBound();
            if (this.m_Solid)
            ...{
                using (SolidBrush brush = new SolidBrush(this.m_BackColor))
                ...{
                    g.FillRectangle(brush, bound);
                }
            }
            using (Pen pen = new Pen(this.m_ForeColor))
            ...{
                g.DrawRectangle(pen, bound);
            }
        }    public override bool Near(int x, int y)
        ...{
            Rectangle bound = this.GetBound();
            Rectangle inner = bound;
            Rectangle outer = bound;
            inner.Inflate(-m_HalfGrab, -m_HalfGrab);
            outer.Inflate(m_HalfGrab, m_HalfGrab);
            Region reg = new Region(outer);
            reg.Exclude(inner);
            return reg.IsVisible(x, y);
        }    public override void SetBound(Rectangle bound)
        ...{
            this.m_Start = new Point(bound.X, bound.Y);
            this.m_End = new Point(bound.Right, bound.Bottom);
        }
    }当然也可以绘制Window控件:class ButtonObj:DrawBase
    ...{
        private Point m_Start;
        private Point m_End;
        private string m_Text;
        public ButtonObj(Point start, Point end)
        ...{
            this.m_Start = start;
            this.m_End = end;
        }
        public string Text
        ...{
            get ...{ return m_Text; }
            set ...{ m_Text = value; }
        }
        public override System.Drawing.Rectangle GetBound()
        ...{
            int x = this.m_Start.X < this.m_End.X ? this.m_Start.X : this.m_End.X;
            int y = this.m_Start.Y < this.m_End.Y ? this.m_Start.Y : this.m_End.Y;
            int r = this.m_Start.X < this.m_End.X ? this.m_End.X : this.m_Start.X;
            int b = this.m_Start.Y < this.m_End.Y ? this.m_End.Y : this.m_Start.Y;
            return Rectangle.FromLTRB(x, y, r, b);
        }    public override void Draw(Graphics g)
        ...{
            Rectangle bound = this.GetBound();
            using (Pen pen = new Pen(this.m_ForeColor))
            ...{
                ControlPaint.DrawButton(g, bound, ButtonState.Normal);
                using (SolidBrush brush = new SolidBrush(this.m_ForeColor))
                ...{
                    using (Font font = new Font("宋体", 10))
                    ...{
                        using (StringFormat format = new StringFormat())
                        ...{
                            format.Alignment = StringAlignment.Center;
                            format.LineAlignment = StringAlignment.Center;
                            g.DrawString(this.m_Text, font, brush, bound, format);
                        }
                    }
                }
            }
        }    public override bool Near(int x, int y)
        ...{
            Rectangle bound = this.GetBound();
            Rectangle outer = bound;
            outer.Inflate(m_HalfGrab, m_HalfGrab);
            return outer.Contains(x, y);
        }    public override void SetBound(Rectangle bound)
        ...{
            this.m_Start = new Point(bound.X, bound.Y);
            this.m_End = new Point(bound.Right, bound.Bottom);
        }
    }
      

  3.   

    定义这些图像的集合对象:class DrawList:List<DrawBase>
    ...{
        private Control m_Owner;
        public DrawList(Control owner)
        ...{ 
            this.m_Owner = owner;
        }
        internal DrawBase GetNear(int x, int y)
        ...{
            foreach (DrawBase draw in this)
            ...{
                if (draw.Near(x, y))
                ...{
                    return draw;
                }
            }
            return null;
        }    internal void Draw(Graphics graphics)
        ...{
            foreach (DrawBase draw in this)
            ...{
                draw.Draw(graphics);
            }
        }
    }
    构建一个Window窗体用来展示图像操作: using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using DrawLines.DrawObjs;namespace DrawLines
    ...{
        public partial class Form1 : Form
        ...{
            private DrawList m_drawList;
            private DrawBase m_curDraw;
            private Rectangle m_curBound;
            private Rectangle m_lastBound;
            private Point m_StartPoint;
            public Form1()
            ...{
                InitializeComponent();
                this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);            this.InitObjs();
            }
            /**//// <summary>
            /// 构造对象
            /// </summary>
            private void InitObjs()
            ...{
                this.m_drawList = new DrawList(this);            DrawBase.HalfGrab = 5;
                LineObj line0 = new LineObj(new Point(10, 10), new Point(100, 100));
                line0.ForeColor = Color.Red;            LineObj line1 = new LineObj(new Point(16, 67), new Point(100, 180));
                line1.ForeColor = Color.Blue;            RectangleObj rect = new RectangleObj(new Point(120, 70), new Point(220, 200));
                rect.ForeColor = Color.Green;            ButtonObj button = new ButtonObj(new Point(20, 20), new Point(90, 45));
                button.ForeColor = Color.Black;
                button.Text = "button1";
                m_drawList.Add(line0);
                m_drawList.Add(line1);
                m_drawList.Add(rect);
                m_drawList.Add(button);
            }
            /**//// <summary>
            /// 绘制对象
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPaint(PaintEventArgs e)
            ...{
                this.m_drawList.Draw(e.Graphics);
                base.OnPaint(e);
            }
            /**//// <summary>
            /// 重写以移动对象或设置鼠标
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseMove(MouseEventArgs e)
            ...{
                base.OnMouseMove(e);
                if (this.Capture)
                ...{
                    if (this.m_curDraw != null)
                    ...{
                        this.moveObj(e);
                    }
                    return;
                }
                if (this.m_drawList.GetNear(e.X, e.Y) != null)
                ...{
                    this.Cursor = Cursors.SizeAll;
                }
                else
                ...{
                    this.Cursor = Cursors.Default;
                }
            }
            /**//// <summary>
            /// 重写以获取鼠标下的对象
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseDown(MouseEventArgs e)
            ...{
                base.OnMouseDown(e);
                this.getObj(e);
            }
            /**//// <summary>
            /// 重写以按Delete键删除当前对象
            /// </summary>
            /// <param name="keyData"></param>
            /// <returns></returns>
            protected override bool ProcessDialogKey(Keys keyData)
            ...{
                if (keyData == Keys.Delete)
                ...{
                    if (this.m_curDraw != null)
                    ...{
                        this.deleteObj();
                    }
                }
                return base.ProcessDialogKey(keyData);
            }
            private void btnDelete_Click(object sender, EventArgs e)
            ...{
                if (this.m_curDraw != null)
                ...{
                    this.deleteObj();
                }
                else
                ...{
                    MessageBox.Show(this, "没有选中的对象,请使用鼠标点选择一个!", "提示");
                }
            }
            private void moveObj(MouseEventArgs e)
            ...{
                Rectangle bound = this.m_curBound;            bound.Offset(e.X - this.m_StartPoint.X, e.Y - this.m_StartPoint.Y);
                this.m_curDraw.SetBound(bound);            Rectangle _last = this.m_lastBound;
                Rectangle _bound = bound;
                _last.Inflate(2, 2);
                _bound.Inflate(2, 2);            using (Region invReg = new Region(_last))
                ...{
                    invReg.Union(_bound);
                    this.Invalidate(invReg);
                }
                this.m_lastBound = bound;
            }
            private void getObj(MouseEventArgs e)
            ...{
                this.m_curDraw = this.m_drawList.GetNear(e.X, e.Y);
                if (this.m_curDraw != null)
                ...{
                    this.m_curBound = this.m_curDraw.GetBound();
                    this.m_StartPoint = e.Location;
                }
            }
            private void deleteObj()
            ...{
                Rectangle bound = this.m_curDraw.GetBound();
                this.m_drawList.Remove(this.m_curDraw);
                this.m_curDraw = null;
                bound.Inflate(2, 2);
                this.Invalidate(bound);
            }
        }
    }
      

  4.   

    GDI编程
     GDI+简单绘图