我确定了图像中的矩形区域,并在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控件
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;
}
这将产生无效的结果。请咨询
2条答案
按热度按时间ep6jt1vc1#
您可以通过以下方式将图片框上的选定矩形转换为图像上的矩形:
注意:你可以在这里找到
ImageRectangleFromSizeMode
方法的源代码,并将其作为应用程序代码的一部分编写。示例-裁剪具有SizeMode = Zoom的PictureBox的图像
例如,以下代码将裁剪图片框1的给定矩形,并将结果设置为图片框2的图像:
下面是输入图像:
这就是结果:
olqngx592#
一个专门的类,提供一些帮助工具来确定选择的缩放因子,并将选择坐标转换为缩放的
Bitmap
坐标。此 * 版本 * 仅适用于缩放图像。
ZoomFactor
类提供了这些方法:PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
:返回容器内Point位置的
PointF
转换坐标到位图内的Point位置,在容器中缩放。RectangleF TranslateZoomSelection(RectangleF Selection, SizeF ContainerSize, SizeF ImageSize)
:返回一个
RectangleF
,表示在容器内创建的选择,转换为位图坐标。RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
:返回一个**
RectangleF
**,表示原始位图的预选区域,该区域转换为容器内的缩放选择图像。PointF GetImageScaledOrigin(SizeF ContainerSize, SizeF ImageSize)
:返回容器内缩放图像原点坐标的
PointF
引用。SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize)
:返回在Container中缩放时Image的
SizeF
引用。示例用法,演示如何使用在Container控件内创建的Rectangle选择裁剪Bitmap。
TranslateZoomSelection
方法返回与选择区域对应的Bitmap部分:上述行为的示例:
注意:* 示例中,Portrait中图像的预选将
Width
和Height
反转 *ZoomFactor
类: