2017-10-05 8 views
1

Dans mon formulaire, j'ai 2 contrôles picturebox. J'ai chargé une image de fond bleu sur pictureBox1 et laissé pictureBox2 contrôle seul. Avec le code ci-dessous, je suis capable de dessiner des flèches sur mon image picturebox1.Peinture Drawline Image dans l'image Picturebox

Objectif: Sur mon événement pictureBox1_MouseUp Je veux ajouter toutes les flèches que je tirais sur pictureBox1 à pictureBox2.

Problème: Le problème est sur mon événement pictureBox1_MouseUp quand j'ai écrit pictureBox2.Image = pictureBox1.Image ne pas ajouter la flèche peinte que je dessinais sur pictureBox1. Il ajoute uniquement l'image pictureBox1 que j'ai affectée dans mon événement de chargement de formulaire.

private bool isMoving = false; 
    private Point mouseDownPosition = Point.Empty; 
    private Point mouseMovePosition = Point.Empty; 
    private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>(); 
    Pen _Pen; 

    private void pictureBox1_Paint(object sender, PaintEventArgs e) 
    { 

     if (isMoving) 
     { 
      if (pictureBox1.Image == null) e.Graphics.Clear(Color.White); 

      // Add this line for high quality drawing: 
      e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 

      AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5); 
      _Pen = new Pen(Color.IndianRed, 3); 
      _Pen.CustomEndCap = bigArrow; 
      e.Graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition); 
      _Pen.Dispose(); 
     } 
    } 

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
     isMoving = true; 
     mouseDownPosition = e.Location; 
    } 

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (isMoving) 
     { 
      mouseMovePosition = e.Location; 
      pictureBox1.Invalidate(); 
     } 
    } 

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 
    { 

     if (isMoving) 
     { 
      lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition)); 
     } 
     isMoving = false; 

     pictureBox2.Image = pictureBox1.Image; 
    } 

enter image description here

Test 1: (Changé Code pictureBox1_Paint)

Avec ce code, il dessine la flèche sur pictureBox2, mais on dirait qu'il dessine plusieurs flèches.

 if (isMoving) 
     { 
      if (pictureBox1.Image == null) e.Graphics.Clear(Color.White); 

      // Add this line for high quality drawing: 
      e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 

      AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5); 
      _Pen = new Pen(Color.IndianRed, 3); 
      Bitmap BitImg = (Bitmap)pictureBox1.Image; 
      _Pen.CustomEndCap = bigArrow; 
      using (var graphics = Graphics.FromImage(BitImg)) 
      { 
       graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition); 
      } 
      pictureBox1.Image = BitImg; 
      _Pen.Dispose(); 
     } 

enter image description here

Test 2:. (Je pris le code de l'événement de peinture et collé, il MouseMove événement avec quelques modifications Cette utilise trop de mémoire et il ne tire pas sur pictureBox1 mais la flèche est maintenant visible dans pictureBox2)

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (isMoving) 
     { 
      mouseMovePosition = e.Location; 

      if (isMoving) 
      { 

       AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5); 
       _Pen = new Pen(Color.IndianRed, 3); 
       BitImg = new Bitmap(pictureBox1.Image);      
       _Pen.CustomEndCap = bigArrow; 
       using (var graphics = Graphics.FromImage(BitImg)) 
       { 
        graphics.SmoothingMode = SmoothingMode.HighQuality; 
        graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition); 
       } 

       _Pen.Dispose(); 
      } 

      pictureBox1.Invalidate(); 

     } 
    } 

enter image description here

Répondre

1

Dessiner toutes les lignes pictureBox1: enter image description here

Le seul inconvénient de la dernière ligne à pictureBox1: enter image description here

En pictureBox2 contrôle, ajoutez événement Paint-pictureBox2_Paint.

Je vous suggère de faire un stylo et une casquette varriable mondiale:

// Make pen and cap global varriable to boost the perfomane. 
// Create and delete them each draw will cost alot of CPU 
Pen pen = new Pen(Color.IndianRed, 3); 
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5); 

En cas Form1(), ajoutez cette ligne:

pen.CustomEndCap = bigArrow; 

et faire comme suit:

public partial class Form1 : Form 
{ 
    private bool isMoving = false; 
    private Point mouseDownPosition = Point.Empty; 
    private Point mouseMovePosition = Point.Empty; 
    private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>(); 

    public Form1() 
    { 
     InitializeComponent(); 
     pen.CustomEndCap = bigArrow; 
    } 

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
     isMoving = true; 
     mouseDownPosition = e.Location; 
    } 

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (isMoving) 
     { 
      mouseMovePosition = e.Location; 
      pictureBox1.Invalidate(); 
     } 
    } 

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 
    { 
     if (isMoving) 
     { 
      lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition)); 
      pictureBox2.Invalidate(); 
     } 
     isMoving = false; 
    } 

    private void pictureBox1_Paint(object sender, PaintEventArgs e) 
    { 
     if (isMoving) 
     { 
      if ((sender as PictureBox).Image == null) e.Graphics.Clear(Color.White); 

      // Add this line for high quality drawing: 
      e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 

      e.Graphics.DrawLine(pen, mouseDownPosition, mouseMovePosition); 

      // If you want draw all previous lines here, add bellow code: 
      //foreach (var line in lines) 
      //{ 
      // e.Graphics.DrawLine(pen, line.Item1, line.Item2); 
      //} 
     } 
    } 

    private void pictureBox2_Paint(object sender, PaintEventArgs e) 
    { 
     if ((sender as PictureBox).Image == null) e.Graphics.Clear(Color.White); 

     e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 
     foreach (var line in lines) 
     { 
      e.Graphics.DrawLine(pen, line.Item1, line.Item2); 
     } 
    } 
} 

code ci-dessus dessiner des lignes au contrôle PictureBox, pas à l'image, cela vous permet de supprimer certaines lignes ou effacer tout lignes que vous dessinez à picturebox si vous voulez plus tard.

Si vous voulez dessiner directement à l'image, les choses événement beaucoup plus facile, vous n'avez pas besoin pictureBox2_Paint du tout:

private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 
{ 
    if (isMoving) 
    { 
     // You event don't need this line 
     //lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition)); 

     if (pictureBox1.Image != null) 
     { 
      using (var g = Graphics.FromImage(pictureBox1.Image)) 
      { 
       g.SmoothingMode = SmoothingMode.HighQuality; 
       g.DrawLine(pen, mouseDownPosition, mouseMovePosition); 
      } 
      pictureBox2.Image = pictureBox1.Image; 
     } 
    } 
    isMoving = false; 
} 

private void pictureBox1_Paint(object sender, PaintEventArgs e) 
{ 
    if (isMoving) 
    { 
     if ((sender as PictureBox).Image == null) e.Graphics.Clear(Color.White); 

     e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 
     e.Graphics.DrawLine(pen, mouseDownPosition, mouseMovePosition); 
    } 
} 

private void pictureBox2_Paint(object sender, PaintEventArgs e) 
{ 
} 
+1

Excellente explication! Cela fonctionne très bien. Je vous remercie! – taji01

+0

Content de t'aider! – Sakura

1

Y Vous avez deux problèmes ici:

  1. Vous peignez sur Contrôle plutôt que sur une image. L'image reste inchangée.

  2. Les deux pictureBox1 et pictureBox2 font référence à la même image. Lorsque vous modifiez l'image, les deux contrôles seront affectés lors de l'événement Paint suivant.

Donc pictureBox1_Paint vous devez créer une copie de pictureBox1.Image (essayez d'utiliser Bitmap), puis la peinture sur elle et affecter l'image mise à jour à pictureBox1.Image. Il sera peint automatiquement.

+0

Andrey, faisiez-vous allusion à quelque chose comme test 1 code que je viens de mettre? – taji01