私が欲しい機能は、マウスを使ってイメージ上のいくつかのオブジェクトの輪郭を描くことです。イメージ上に輪郭を表示し、輪郭データをエクスポートすることができます。私はここにcyotek.imageboxを使用していますhttps://github.com/cyotek/Cyotek.Windows.Forms.ImageBox、画像を表示するためのカスタムコントロール。 ここに私のアプローチです。Cyotek.ImageBoxでC#winformでマウスで輪郭を描きます。
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
}
}
draw contour_tempパーツが問題なく動作します。しかし、輪郭が完成した図面が破損し、System.ArgumentOutOfRangeExceptionを 'mscorlib.dll'に投げたときにプログラムがクラッシュする。 いくつかのテストの後、塗装機能のすべての輪郭を描画することが何とか間違っている。私はリストのインデックス が範囲外であると言って、例外に関するいくつかの調査を行った。しかし、私が "foreach"を使用しているとどうしてそれが起こるのですか?
ありがとうございました。今それは完璧に動作します! –
また、便利なイメージボックスコントロールについてもう一度感謝します。 ところで、私はimageboxについてのCyotekフォーラムの別の質問をしました。あなたは見てみることができますか? –