我有一个带有图片框的c#WinForms项目,其中包含带文本的文档。我正在使用Google Cloud Vision API收集文档的OCR数据,效果很好。使用从Google API返回的边界矩形,我使用DrawRectangle在每个单词周围绘制矩形,并在此过程中我将该矩形与基础单词相关联。我需要做什么才能只需点击任何给定的矩形并确切地知道它是哪个矩形而不必点击所有矩形的所有坐标直到我找到它。
答案 0 :(得分:3)
ya OP的四个选项
点击点并循环遍历所有矩形的所有坐标,直到找到它为止
这实际上是最简单的答案,并且可能是相对较小(<1000)矩形的最佳表现答案。如果你的矩形可能重叠,请务必从前到后以z顺序存储和循环它们。
如果你有一堆垃圾,你可以创建一个额外的数据结构来协助查找。例如,您可以定义一个10x10数组,其中每个元素都包含与屏幕的一部分重叠的矩形列表。这样你就可以缩小搜索范围。当然,维护列表还有额外的开销,因此可能不值得,具体取决于您的使用特性。
作为替代方案,您可以完全更改方法并将每个矩形渲染为自己的custom control。作为自定义控件,它将具有与任何Win32窗口一样的单击事件处理程序。但是,在实例化和管理所有这些控件时会产生相当大的开销,因此不推荐用于大量矩形。此外,我非常确定它最终会使用上述相同的查找算法,因此它不会更好地执行。
最后一个选项是专门为矩形创建一个类,&#34; bind&#34;它到PictureBox(注册为其事件的消费者)。然后,如果点击位于其边界内,则每个矩形都将处理click事件并引发自己的事件。这是一个让你入门的例子:
class ClickableRectangle
{
private Rectangle _box;
public event EventHandler Click;
public ClickableRectangle(Rectangle coordinates)
{
_box = coordinates;
}
public void BindToControl(Control control)
{
control.MouseUp += Control_MouseUp;
control.Paint += Control_Paint;
}
private void Control_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Black, _box);
}
private void Control_MouseUp(object sender, MouseEventArgs e)
{
if (!_box.Contains(e.X, e.Y)) return;
if (Click != null) Click(this, e);
}
}
然后在MyPictureBox
中显示新的矩形,并使用名为MyClickHandler
的方法处理它们,只需调用
var r = new ClickableRectangle(myRectangle);
r.BindToControl(MyPictureBox);
r.Click += this.MyClickHandler;
瞧。