La fonction que je veux est de permettre à l'utilisateur d'utiliser la souris pour dessiner les contours de plusieurs objets sur l'image. Afficher les contours sur l'image et pouvoir exporter les données de contours. J'utilise cyotek.imagebox ici https://github.com/cyotek/Cyotek.Windows.Forms.ImageBox, un contrôle personnalisé pour l'affichage de l'image. Voici mon approche.dessiner des contours avec la souris sur Winform C# avec Cyotek.ImageBox
private List<List<Point>> contours = new List<List<Point>>(); //a list to store all contours
private List<Point> contour_temp= new List<Point>(); //a list to store the contour the user is drawing
private bool mousedown // a flag that change when mouse up/mouse down event is triggered
private void imageBox_MouseDown(object sender, MouseEventArgs e)
{
mousedown = true;
}
private void imageBox_MouseUp(object sender, MouseEventArgs e)
{
mousedown = false;
}
private void imageBox_MouseMove(object sender, MouseEventArgs e)
{
//drawing occurs when mouse is down, a contour is finish drawing when mouse is up
// when a contour finish drawing. it will be added to the contours list and the contour temp will be clear
if (draw_on) // a flag for this function to be active
{
if (contour_temp.Count > 0)
{
if (mousedown)
{
if (imageBox.IsPointInImage(e.Location)) //function cyotek.imagebox provides , it translate the mouse location to pixel location
{
Point p = this.imageBox.PointToImage(e.Location);
if (p != contour_temp[contour_temp.Count - 1])
contour_temp.Add(p);
}
}
else
{
if (contour_temp.Count > 2)
{
contours.Add(contour_temp);
contour_temp.Clear();
}
}
}
else
{
if (mousedown)
{
contour_temp = new List<Point>();
Point p = this.imageBox.PointToImage(e.Location);
contour_temp.Add(p);
}
}
imageBox.Invalidate();
}
}
private void imageBox_Paint(object sender, PaintEventArgs e)
{
//at the painting function, always paint all the contours stored
//if mouse is down, print the temporary contour the user is currently drawing
foreach (List<Point> contour in contours)
{
Point p0 = contour[0];
foreach (Point p1 in contour)
{
e.Graphics.DrawLine(new Pen(Color.Red), imageBox.GetOffsetPoint(p0), imageBox.GetOffsetPoint(p1));//Cyotek.ImageBox provided, get the correct point even after zooming
p0 = p1;
} //draw all contours
}
if(draw_on && mousedown && contour_temp.Count>0)
{
Point p0 = contour_temp[0];
foreach (Point p1 in contour_temp)
{
e.Graphics.DrawLine(new Pen(Color.Green), imageBox.GetOffsetPoint(p0), imageBox.GetOffsetPoint(p1));
p0 = p1;
}// draw the contour user is drawing
}
}
La partie dessiner contour_temp fonctionne correctement. Mais le programme plante quand un contour a fini de dessiner, en lançant System.ArgumentOutOfRangeException sur 'mscorlib.dll', Après quelques tests, je découvre que la chose dessiner tous les contours dans la fonction de peinture est en quelque sorte fausse. J'ai fait quelques recherches sur l'exception, en disant que l'index de la liste est hors limite. Mais comment cela est-il arrivé quand j'utilise "foreach"?
Merci. Maintenant, cela fonctionne parfaitement! –
Et encore merci pour le contrôle de l'imagebox pratique. En passant, j'ai posé une autre question sur le forum Cyotek à propos de l'imagebox. Pourriez-vous jeter un coup d'oeil? –