c# - 在缩放模式下平移矩形位置 Picturebox
问题描述
我正在确定图像中的矩形区域并在 PictureBox 中将其显示给用户。
由于图像有时可能非常大,因此我使用的是SizeMode
设置为Zoom
.
我正在使用以下代码来转换 Rectangle (X, Y) 坐标:
public Point TranslateZoomMousePosition(Point coordinates)
{
// test to make sure our image is not null
if (pictureBox5.Image == null) return coordinates;
// Make sure our control width and height are not 0 and our
// image width and height are not 0
if (pictureBox5.Width == 0 || pictureBox5.Height == 0 || pictureBox5.Image.Width == 0 || pictureBox5.Image.Height == 0) return coordinates;
// This is the one that gets a little tricky. Essentially, need to check
// the aspect ratio of the image to the aspect ratio of the control
// to determine how it is being rendered
float imageAspect = (float)pictureBox5.Image.Width / pictureBox5.Image.Height;
float controlAspect = (float)pictureBox5.Width / pictureBox5.Height;
float newX = coordinates.X;
float newY = coordinates.Y;
if (imageAspect > controlAspect)
{
// This means that we are limited by width,
// meaning the image fills up the entire control from left to right
float ratioWidth = (float)pictureBox5.Image.Width / pictureBox5.Width;
newX *= ratioWidth;
float scale = (float)pictureBox5.Width / pictureBox5.Image.Width;
float displayHeight = scale * pictureBox5.Image.Height;
float diffHeight = pictureBox5.Height - displayHeight;
diffHeight /= 2;
newY -= diffHeight;
newY /= scale;
}
else
{
// This means that we are limited by height,
// meaning the image fills up the entire control from top to bottom
float ratioHeight = (float)pictureBox5.Image.Height / pictureBox5.Height;
newY *= ratioHeight;
float scale = (float)pictureBox5.Height / pictureBox5.Image.Height;
float displayWidth = scale * pictureBox5.Image.Width;
float diffWidth = pictureBox5.Width - displayWidth;
diffWidth /= 2;
newX -= diffWidth;
newX /= scale;
}
return new Point((int)newX, (int)newY);
}
在确定的位置添加框架控件:
pictureBox5.Controls.Clear();
var c = new FrameControl();
c.Size = new Size(myrect.Width, myrect.Height);
c.Location=TranslateZoomMousePosition(newPoint(myrect.Location.X,myrect.Location.Y));
pictureBox5.Controls.Add(c);
但是确定的框架/矩形位置不正确。
我在做什么错?
更新:我正在尝试使用类似的代码将图像上的 Rectangle 转换为 PictureBox 上的 Frame Control
public Rectangle GetRectangeOnPictureBox(PictureBox p, Rectangle selectionRect,Bitmap bit)
{
var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var imageRect = (Rectangle)method.Invoke(p, new object[] { p.SizeMode });
if (p.Image == null)
return selectionRect;
int cx = bit.Width / imageRect.Width;
int cy = bit.Height / imageRect.Height;
Rectangle trsRectangle = new Rectangle(selectionRect.X * cx, selectionRect.Y * cy, selectionRect.Width * cx, selectionRect.Height * cy);
trsRectangle.Offset(imageRect.X, imageRect.Y);
return trsRectangle;
}
这会产生无效的结果。请咨询
解决方案
您可以通过以下方式将图片框上的选定矩形转换为图像上的矩形:
public RectangleF GetRectangeOnImage(PictureBox p, Rectangle selectionRect)
{
var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var imageRect = (Rectangle)method.Invoke(p, new object[] { p.SizeMode });
if (p.Image == null)
return selectionRect;
var cx = (float)p.Image.Width / (float)imageRect.Width;
var cy = (float)p.Image.Height / (float)imageRect.Height;
var r2 = Rectangle.Intersect(imageRect, selectionRect);
r2.Offset(-imageRect.X, -imageRect.Y);
return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
}
注意:您可以在此处找到ImageRectangleFromSizeMode
方法源代码并将其用作编写此类方法作为应用程序代码的一部分。
示例 - 裁剪具有 SizeMode = Zoom 的 PictureBox 的图像
例如,以下代码将裁剪图片框 1 的给定矩形,并将结果设置为图片框 2 的图像:
var selectedRectangle = new Rectangle(7, 30, 50, 40);
var result = GetRectangeOnImage(pictureBox1, selectedRectangle);
using (var bm = new Bitmap((int)result.Width, (int)result.Height))
{
using (var g = Graphics.FromImage(bm))
g.DrawImage(pictureBox1.Image, 0, 0, result, GraphicsUnit.Pixel);
pictureBox2.Image = (Image)bm.Clone();
}
这是输入图像:
这是结果:
推荐阅读
- python - 为什么在为 Raspberry Pi (linux/arm/v7) 构建 docker 映像时“pip install”步骤非常慢?
- android - Android/Ios 到 kinect
- html - Flexbox - 图像随列消失
- python - 在 macOS 上安装 Python
- c# - 编辑从 LINQ 得到的数据结果
- python - 舍入 pyodbc 变量
- python - 如何将多个用户输入附加到python中的字典?
- css - 如何使用 tailwindcss & react 进行页面转换?
- javascript - 反应登录 friebase 版本 8.0.2
- linux - Mosquitto MQTT tls 配置因 TLS 错误而失败