Tracé de ligne pictureBox [Résolu]

sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 31 mai 2016 à 08:12 - Dernière réponse : sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention
- 8 juin 2016 à 08:36
Bonjour à tous,

J'aurai voulu savoir comment tracer une ligne dans une pictureBox à partir de la souris. J'arrive à tracer ça en écrivant les coordonnées dans le programme, mais je souhaiterai que l'utilisateur puisse tracer sa ligne où il le souhaite.

Merci d'avance,

Sebbur
Afficher la suite 

25 réponses

Répondre au sujet
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 31 mai 2016 à 11:51
+1
Utile
Bonjour

il faut que tu te serves des évènements de la souris dans le picturebox.

Par exemple:
  • un premier click => récupération du point de départ (position de la souris),
  • un deuxième click => récupération du point du point d'arrivée et traçage.


Pour que cela soit plus ergonomique, tu peux aussi, après le premier click, tracer une ligne à chaque déplacement de la souris et effacer la précédente, avec l'évènement mouseover.



Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Whismeril
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 1 juin 2016 à 17:36
+1
Utile
Bon

déjà, ça ne sert à rien de convertir de convertir un int en string et d'en refaire un int plus loin.
Autant enregistrer la valeur directe en int.

Pour info, convertir un string en int, il y a 2 options:
int toto = Convert.ToInt32("1");
int tutu = int.Parse("2");


D'autre part, tel que tu as prévu ton truc, pour que ça marche il faut que l'utilisateur maintienne la souris enfoncée le temps de tracer la ligne.
En ce qui me concerne, je ne trouve pas ça pratique, je préfère un click par point, mais c'est toi qui vois.

Voici mon option
       int x1 = -1;
        int y1 = -1;
        int x2 = -1;
        int y2 = -1;

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {

            if (x1 == -1)
            {
                x1 = e.X;
                y1 = e.Y;
            }
            else
            {
                x2 = e.X;
                y2 = e.Y;
            }
        }

public void DrawLineInt(PaintEventArgs e)
        {
            Pen blackPen = new Pen(Color.Red, 3);

    //ici ton code pour déssiner la ligne

    //réinit des valeurs
            x1 = -1;
            y1 = -1;
            x2 = -1;
            y2 = -1;

        }


Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Whismeril
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 5 juin 2016 à 21:42
+1
Utile
D'abord, il faut stocker les les lignes précédentes.
Par ligne on a besoin des 4 coordonnées, et éventuellement de la couleur si on veut varier (par exemple rouge celle en cours, et bleu les précédentes).
J'écris donc une classe qui stocke ça. Pour le coup, y'a pas plus simple comme classe:
using System.Drawing;

namespace Test_Winform
{
    class Segment
    {
       public Point Point1 { get; set; }

       public Point Point1 { get; set; }

       public Color Couleur { get; set; }
    }
}



Dans la Form, il faut gérer la collections de segments (une list<t>) et traiter les lignes sauvegardées et celle en cours
       List<Segment> segments = new List<Segment>();
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Pen blackPen;
            //Lignes précendentes
            foreach (Segment s in segments)
            {
                blackPen = new Pen(s.Couleur, 3);
                e.Graphics.DrawLine(blackPen,s.Point1,s.Point2);
            }


            //Gestion de la ligne en cours
            blackPen = new Pen(Color.Red, 3);

            if (x1 != -1)
            {
                e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);


                if (fin2ligne)
                {
                    //enregistre la ligne
                    segments.Add(new Segment(x1, y1, x2, y2, Color.Blue));

                    //réinit des valeurs
                    x1 = -1;
                    y1 = -1;
                    x2 = -1;
                    y2 = -1;
                }
            }
        }


Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Whismeril
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 31 mai 2016 à 11:57
0
Utile
Je te remercie de ta réponse et de ton aide !

Je vais, dans un premier temps, essayer un tracé simple et une fois réussi, je ferai tout ça de manière plus ergonomique avec les indications que tu m'as fournies.

Merci encore une fois,

Sebbur
Commenter la réponse de sebbur
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 31 mai 2016 à 13:47
0
Utile
En revanche je rencontre un problème quand je veux assigner la position de départ à ma variable.

J'ai créé une méthode pour dessiner la ligne. Les valeurs des variables de coordonnées je les récupère dans les évènements MouseDown et MouseUp. Du coup il est impossible de convertir le string de la variable de mon évènement en int de ma variable de la méthode.

Si je n'ai pas été suffisamment clair, n'hésitez pas à me demander des précisions.

Merci d'avance,

Sebbur
Commenter la réponse de sebbur
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 31 mai 2016 à 18:16
0
Utile
Peux tu poster le code que tu as utilisé, en utilisant cette procédure
http://codes-sources.commentcamarche.net/faq/10686-le-nouveau-codes-sources-comment-ca-marche#balises-code
Commenter la réponse de Whismeril
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 1 juin 2016 à 08:48
0
Utile
Bien sûr, le voici :

public void DrawLineInt(PaintEventArgs e)
        {
            Pen blackPen = new Pen(Color.Red, 3);

            int x1 = a1;
            int y1 = a2;
            int x2 = b1;
            int y2 = b2;

        }

        string a1, a2, b1, b2;
        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            // Récupération de la position de départ
            a1 = e.X.ToString();
            a2 = e.Y.ToString();

        }

        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            // Récupération de la position d'arrivée
            b1 = e.X.ToString();
            b2 = e.Y.ToString();
        }


Mon code est faux, j'en suis conscient, mais je ne vois pas bien comment faire autrement.

Merci de ton aide,

Sebbur
Commenter la réponse de sebbur
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 2 juin 2016 à 08:57
0
Utile
Je te remercie pour ta réponse.

J'ai bien compris ton code et il doit convenir à ma problématique, mais quand je l'ai testé rien ne se passe, c'est-à-dire que quand j'essaie de tracer une ligne avec la souris elle ne se trace pas.

Merci de ton aide,

Sebbur
Commenter la réponse de sebbur
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 2 juin 2016 à 14:53
0
Utile
1
Peux tu montrer le code pour dessiner?
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 2 juin 2016 à 14:59
Voici ma ligne de code pour le dessin de la ligne :

e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);
Commenter la réponse de Whismeril
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 2 juin 2016 à 18:53
0
Utile
La méthode que tu utilises ne peut marcher qu'abonnée à l'événement Paint du contrôle.
Sinon le "e", on y a pas accès.
Si on veut abonner ta méthode à l'évènement Paint, ça ne veut pas car, la signature n'est pas bonne.
Le plus simple dans la fenêtre des évènements, tu doubles click sur Paint, ça va te créer une méthode qui va bien et l'abonnée.

Encore faut il que cet événement soit déclenché, pour ça il faut forcer un Refresh au moment opportun.

        int x1 = -1;
        int y1 = -1;
        int x2 = -1;
        int y2 = -1;

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {


            if (x1 == -1)
            {
                x1 = e.X;
                y1 = e.Y;
            }
            else
            {
                x2 = e.X;
                y2 = e.Y;

                pictureBox1.Refresh();
            }
        }

 
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Pen blackPen = new Pen(Color.Red, 3);

            e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);

            //réinit des valeurs
            x1 = -1;
            y1 = -1;
            x2 = -1;
            y2 = -1;
        }


Et avec la ligne qui suit la souris entre deux clicks
        int x1 = -1;
        int y1 = -1;
        int x2 = -1;
        int y2 = -1;
        bool fin2ligne = false;
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (x1 == -1)
            {
                x1 = e.X;
                y1 = e.Y;
            }
            else
            {
                x2 = e.X;
                y2 = e.Y;
                fin2ligne = true;
                pictureBox1.Refresh();
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {

            if (x1 == -1) return;
            x2 = e.X;
            y2 = e.Y;
            fin2ligne = false;
          
            pictureBox1.Refresh();

        }


        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {

            Pen blackPen = new Pen(Color.Red, 3);

            if (x1 != -1)
            {
                e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);


                if (fin2ligne)
                {
                    //réinit des valeurs
                    x1 = -1;
                    y1 = -1;
                    x2 = -1;
                    y2 = -1;
                }
            }
        }
Commenter la réponse de Whismeril
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 3 juin 2016 à 08:50
0
Utile
2
Je te remercie pour ton aide et tes indications, le code marche très bien !

Il y a juste une chose que je n'ai pas bien compris. Pourquoi initialiser les valeurs à -1 et non pas à 0 ?
vb95 1387 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 3 juin 2016 à 12:16
Bonjour
Le point 0,0,existe : c'est celui qui est tout en haut à gauche de ta Form
Le point -1,-1 est en dehors de ta Form donc impossible d'avoir cette valeur au clic de la souris !
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention > vb95 1387 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 14 décembre 2017 Dernière intervention - 3 juin 2016 à 13:57
Tout à fait.
Cela évite de se trimbaler un boolean supplémentaire pour savoir si une ligne est commencée ou pas.

Comme tu n'as pas précisé si tu veux tracer plusieurs lignes, je ne l'ai pas prévu.
En l'état, toute nouvelle ligne efface la précédente.
Commenter la réponse de sebbur
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 5 juin 2016 à 13:22
0
Utile
Je vous remercie pour vos indications, je comprends mieux les coordonnées -1;-1 maintenant.

Oui c'est vrai que je ne l'ai pas précisé. C'est très bien comme ça pour le moment. Mais si jamais je souhaiterais que la ligne précédente ne soit pas effacée, comment je peux faire ?

Merci encore.

Sebbur
Commenter la réponse de sebbur
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 5 juin 2016 à 15:45
0
Utile
Il faudra stocker les coordonnées des lignes précédentes, et les redessiner à chaque fois. Je te ferai un exemple plus tard.
Commenter la réponse de Whismeril
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 5 juin 2016 à 15:52
0
Utile
D'accord pas de soucis, merci beaucoup !
Commenter la réponse de sebbur
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 6 juin 2016 à 11:42
0
Utile
Merci d'avoir prit le temps de m'illustrer ça à travers un exemple. Je vais essayer ça tout de suite !

Encore merci,

Sebbur
Commenter la réponse de sebbur
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 6 juin 2016 à 13:09
0
Utile
6
Voici mon code que j'ai testé.

public Form1()
        {
            InitializeComponent();
        }
        int x1 = -1;
        int y1 = -1;
        int x2 = -1;
        int y2 = -1;
        bool fin2ligne = false;

        class Segment
        {
            public Point Point1 { get; set; }
            public Point Point2 { get; set; }
            public Color Couleur { get; set; }
        }
        List<Segment> segments = new List<Segment>();

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Pen blackPen;
            //Lignes précédentes
            foreach (Segment s in segments)
            {
                blackPen = new Pen(s.Couleur, 3);
                e.Graphics.DrawLine(blackPen, s.Point1, s.Point2);
            }

            //Gestion de la ligne en cours
            blackPen = new Pen(Color.Red, 3);

            if (x1 != -1)
            {
                e.Graphics.DrawLine(blackPen, x1, y1, x2, y2);

                if (fin2ligne)
                {
                    //enregistre la ligne
                    segments.Add(new Segment(x1, y1, x2, y2, Color.Blue));

                    //réinitialisation des valeurs
                    x1 = -1;
                    y1 = -1;
                    x2 = -1;
                    y2 = -1;
                }
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (x1 == -1) return;
            x2 = e.X;
            y2 = e.Y;
            fin2ligne = false;

            pictureBox1.Refresh();
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (x1 == -1)
            {
                x1 = e.X;
                y1 = e.Y;
            }
            else
            {
                x2 = e.X;
                y2 = e.Y;
                fin2ligne = true;
                pictureBox1.Refresh();
            }
        }


J'ai une erreur au moment où j'enregistre la ligne.
L'erreur : 'Form1.Segment' ne contient pas de constructeur qui accepte des arguments 5
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention > Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 6 juin 2016 à 16:23
D'accord pas de soucis, merci et à plus tard.

Sebbur
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 6 juin 2016 à 17:34
using System.Drawing;

namespace Test_Winform
{
    class Segment
    {
        public Segment(int X1, int Y1, int X2, int Y2, Color Couleur)
        {
            Point1 = new Point(X1, Y1);
            Point2 = new Point(X2, Y2);
            this.Couleur = Couleur;
        }

       public Point Point1 { get; set; }

       public Point Point2 { get; set; }

       public Color Couleur { get; set; }
    }
}
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention - 7 juin 2016 à 17:16
Merci beaucoup, ça fonctionne très bien !

Merci d'avoir prit le temps de m'aider, c'est sympa ! ;)

Sebbur
Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 7 juin 2016 à 18:13
De rien, tu,peux marquer le sujet résolu, si cela te convient.
sebbur 39 Messages postés lundi 9 mai 2016Date d'inscription 27 juillet 2016 Dernière intervention > Whismeril 10555 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 15 décembre 2017 Dernière intervention - 8 juin 2016 à 08:36
Voilà qui est fait.
Encore merci pour ton aide.

Sebbur
Commenter la réponse de sebbur

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.