none
Как правильно нужно оформить метод для рисования на C#? RRS feed

  • Вопрос

  • Здравствуйте!
    Я пишу небольшую программу которая должна давать пользователю возможность рисовать мышкой. В принципе у меня все получилось, но меня беспокоит то как оно рисует линию, вот код метода:

    private void mainPictureBox_MouseDown(object sender, MouseEventArgs e)
    {
       startPoint = e.Location;
    }
    
    private void mainPictureBox_MouseMove(object sender, MouseEventArgs e)
    {
       if (e.Button == MouseButtons.Left)
       {
          drawPen = new Pen(penColorGlobal, penSizeTrackBar.Value);
          movePoint = e.Location;
          Graphics g = Graphics.FromImage(mainPictureBox.Image);
          g.DrawLine(drawPen, startPoint, movePoint);
          startPoint = movePoint;      drawPen.Dispose();
          g.Dispose();
          mainPictureBox.Invalidate();
       }
    }


    В коде видно что при опускании мыши на рисунок (MouseDown) мы заносим в объект startPoint типаPoint начальные координаты, то есть координаты откуда начинаем рисовать. В самом методеMouseMove мы указываем что рисовать мы будем линию от startPoint до movePoint (movePoint - траектория по которой движется наша мышь).
    Все работает, но есть одно но... Если внимательно присмотреться то можно увидеть что нарисованная нами линия по диагонали (допустим) будет состоять не из сплошной линии а из каких-то крестиков 0о! Это особенно заметно при увеличении размера линии.

    Подскажите пожалуйста как можно это исправить, или может я где-то допустил ошибку в коде, если так то исправьте.
    Заранее всем Спасибо!

    20 февраля 2012 г. 18:50

Ответы

  • > небольшую программу которая должна давать пользователю возможность рисовать мышкой.
     
     
    пример позволяет рисовать мышью. сохраняет линии. и подсвечивать линии под мышью.
     

    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    using System.Linq;
    
    namespace WindowsFormsApplication4
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
                this.Shapes = new List<GraphicsPath>();
                this.Points = new List<Point>();
            }
    
            List<GraphicsPath> Shapes;
            List<Point> Points;
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                base.OnMouseMove(e);
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    this.Points.Add(e.Location);
                    this.Invalidate();
                }
                else
                {
                    if(this.Shapes.Any(x => x.IsVisible(e.Location)))
                        this.Invalidate();
                }
            }
    
            protected override void OnMouseUp(MouseEventArgs e)
            {
                base.OnMouseUp(e);
                if(this.Points.Count > 2)
                {
                    var gp = new GraphicsPath();
                    gp.AddCurve(this.Points.ToArray());
                    this.Shapes.Add(gp);
    
                    this.Points = new List<Point>();
                }
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                if (this.Points.Count > 2)
                {
                    using(var p = new Pen(Color.Red, 2))
                        e.Graphics.DrawCurve(p, Points.ToArray());
                }
                foreach(var gp in this.Shapes)
                {
                    var c = gp.IsVisible(this.PointToClient(Control.MousePosition)) ? Color.Blue : Color.Silver;
                    using(var p = new Pen(c))
                        e.Graphics.DrawPath(p, gp);
                }
            }
        }
    }
    
      
      
    • Помечено в качестве ответа Kris_Simpson 22 февраля 2012 г. 9:32
    21 февраля 2012 г. 13:21

Все ответы

  • Здравствуйте.

    Вот статья на MSDN по вашему вопросу, она должна решить проблему - Сглаживание прямых и кривых линий

    Перед рисованием линии вам нужно добавить сглаживание:

    myGraphics.SmoothingMode = SmoothingMode.AntiAlias;

    Не забудьте отметить ответ, если он решит проблему (кнопка 'Пометить как ответ').

    Спасибо.


    Для связи [mail]

    • Помечено в качестве ответа Kris_Simpson 21 февраля 2012 г. 11:37
    • Снята пометка об ответе Kris_Simpson 21 февраля 2012 г. 11:41
    21 февраля 2012 г. 6:31
  • К сожалению это не помогает. Я уже пробовал так делать. Эвект конечно лучше но все равно не то.

    private void mainPictureBox_MouseMove(object sender, MouseEventArgs e)
    {
       if (e.Button == MouseButtons.Left)
       {
          Pen drawPen = new Pen(penColorGlobal, 1);
          Brush fillBrush = new SolidBrush(penColorGlobal);
          size = penSizeTrackBar.Value;
    
          Rectangle rectangle = new Rectangle(startPoint.X - (size / 2), startPoint.Y - (size / 2), size, size);
    
          Graphics g = Graphics.FromImage(mainPictureBox.Image);
    
          g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    
          g.FillEllipse(fillBrush, rectangle);
          g.DrawEllipse(drawPen, rectangle);
    
          startPoint = e.Location;
    
          drawPen.Dispose();
          g.Dispose();
    
          mainPictureBox.Invalidate();
       }
    }

    немного повозившись мой код принял такой вид. Но всеравно не то. При быстром перемещении мышки линия теряет "форму" и рисуются просто круги. Вот скриншот:



    • Изменено Kris_Simpson 21 февраля 2012 г. 11:51 Не вставил блок с кодом
    21 февраля 2012 г. 11:44
  • Так вы хотите нарисовать кривую линию?

    Тогда вам нужно смотреть в сторону Graphics.DrawPath, чтобы отдельные точки соединялись с помощью дуг или прямых линий.

    Иначе у вас при быстром движении мыши так и будут отдельные точки, потому что частота замера меньше, чем скорость с которой вы рисуете.


    Для связи [mail]

    21 февраля 2012 г. 12:00
  • > небольшую программу которая должна давать пользователю возможность рисовать мышкой.
     
     
    пример позволяет рисовать мышью. сохраняет линии. и подсвечивать линии под мышью.
     

    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    using System.Linq;
    
    namespace WindowsFormsApplication4
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
                this.Shapes = new List<GraphicsPath>();
                this.Points = new List<Point>();
            }
    
            List<GraphicsPath> Shapes;
            List<Point> Points;
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                base.OnMouseMove(e);
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    this.Points.Add(e.Location);
                    this.Invalidate();
                }
                else
                {
                    if(this.Shapes.Any(x => x.IsVisible(e.Location)))
                        this.Invalidate();
                }
            }
    
            protected override void OnMouseUp(MouseEventArgs e)
            {
                base.OnMouseUp(e);
                if(this.Points.Count > 2)
                {
                    var gp = new GraphicsPath();
                    gp.AddCurve(this.Points.ToArray());
                    this.Shapes.Add(gp);
    
                    this.Points = new List<Point>();
                }
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                if (this.Points.Count > 2)
                {
                    using(var p = new Pen(Color.Red, 2))
                        e.Graphics.DrawCurve(p, Points.ToArray());
                }
                foreach(var gp in this.Shapes)
                {
                    var c = gp.IsVisible(this.PointToClient(Control.MousePosition)) ? Color.Blue : Color.Silver;
                    using(var p = new Pen(c))
                        e.Graphics.DrawPath(p, gp);
                }
            }
        }
    }
    
      
      
    • Помечено в качестве ответа Kris_Simpson 22 февраля 2012 г. 9:32
    21 февраля 2012 г. 13:21