c# - 在图片框内绘制矩形 SizeMode Zoom
问题描述
我在 WindowsForms 项目中有一个图片框,其 SizeMode 为“缩放”。
我想在图像内绘制一个矩形并获取其相对于图像而不是图片框的坐标。
问题是矩形的坐标与在 Windows Paint Application 上选择的相同矩形不匹配。
这是使用的代码:
开始绘画:
/// <summary> /// Starts drawing. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { backupImage = pictureBox1.Image; _once = true; RectStartPoint = e.Location; pictureBox1.Invalidate(); }
移动鼠标时:
/// <summary> /// While moving mouse event, paint rectangle /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (_once) //Only draw rectangle while drawing mode { Point tempEndPoint = e.Location; Rect.Location = new Point(Math.Min(RectStartPoint.X, tempEndPoint.X), Math.Min(RectStartPoint.Y, tempEndPoint.Y)); Rect = new Rectangle( Math.Min(tempEndPoint.X, Rect.Left), Math.Min(tempEndPoint.Y, Rect.Top), Math.Min(e.X - RectStartPoint.X, pictureBox1.ClientRectangle.Width - RectStartPoint.X), Math.Min(e.Y - RectStartPoint.Y, pictureBox1.ClientRectangle.Height - RectStartPoint.Y)); pictureBox1.Refresh(); pictureBox1.CreateGraphics().DrawRectangle(cropPen, Rect); } }
单击 2 时,完成绘制矩形:
/// <summary> /// When mouse click is released, write in texbox the rectangle's coordinates. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { if (_once) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { Point tempEndPoint = e.Location; _once = false; string sAux = string.Format("Left: {0}; Top: {1}; Width: {2}; Height: {3} \r\n", Math.Min(tempEndPoint.X, Rect.Left), Math.Min(tempEndPoint.Y, Rect.Top), Math.Min(e.X - RectStartPoint.X, pictureBox1.ClientRectangle.Width - RectStartPoint.X), Math.Min(e.Y - RectStartPoint.Y, pictureBox1.ClientRectangle.Height - RectStartPoint.Y)); textBox1.Text += sAux; } } }
结果是:
正如您在两张图片上看到的,左侧、顶部、宽度和高度不匹配。
你能告诉我如何获得相同的结果吗?
解决方案
这是一个帮助进行各种计算的函数:
void SetImageScale(PictureBox pbox, out RectangleF ImgArea, out float zoom)
{
SizeF sp = pbox.ClientSize;
SizeF si = pbox.Image.Size;
float rp = sp.Width / sp.Height; // calculate the ratios of
float ri = si.Width / si.Height; // pbox and image
if (rp > ri)
{
zoom = 1f * sp.Height / si.Height;
float width = si.Width * zoom;
float left = (sp.Width - width) / 2;
ImgArea = new RectangleF(left, 0, width, sp.Height);
}
else
{
zoom = 1f * sp.Width / si.Width;
float height = si.Height * zoom;
float top = (sp.Height - height) / 2;
ImgArea = new RectangleF(0, top, sp.Width, height);
}
}
Rectangle Rect
给定从鼠标坐标创建的a ,这是您如何使用它的方法:
float zoom = 1f;
RectangleF ImgArea = Rectangle.Empty;
SetImageScale(pictureBox1, out ImgArea, out zoom);
Point RLoc = Point.Round(new PointF( (Rect.X - ImgArea.X) / zoom,
(Rect.Y - ImgArea.Y) / zoom ));
Size RSz = Size.Round(new SizeF(Rect.Width / zoom, Rect.Height / zoom));
label1.Text = "Selection in mouse coordinates: " + Rect.ToString();
label2.Text = "Selection in image coordinates: " + new Rectangle(RLoc, RSz).ToString();
无论图像是横向还是纵向,或者图像的比例或图片框的比例更大,这都应该有效。
请注意,随着图像的强烈缩放,很难进行像素完美的选择。
该功能是本文中功能的变体。
推荐阅读
- android - 是否可以在 Android 上强制或找出本机分辨率?
- javascript - 对于函数中的默认 DATE 参数,我必须在 Oracle 中检查哪些数据库参数?
- android - 当我更新我的 Android Studio 时,我得到一个字符串数组无法解析错误
- c# - 无法将文件从 Angular 8 上传到 .net core 2.2?
- python - 是否可以在 Azure Web App (Linux) 上的主机操作系统上安装包
- conda - 在检查目录属性时,conda 环境的磁盘使用量似乎比实际更大?
- google-cloud-platform - 大三角帆 UI 卡在身份验证上并最终超时
- reactjs - 重置输入字段 - 在屏幕上保持打印状态
- rust - 如何静态断言函数的结束是不可达的
- python - Fluentd - 使用 python 发送 json