缩小矩形以使其在大原始图像中显示

时间:2018-12-24 06:02:05

标签: c# .net winforms system.drawing

我正在PictureBox中显示图像,并允许用户通过提供矩形的宽度和高度来指定图像中的区域。矩形的位置以编程方式确定。

图片框中显示的图像按比例缩小以节省处理时间。因此,如果用户指定200X200矩形,则在预览图像中看起来可能很大,但在原始图像中会很小,可能会很大。

如何缩小或转换矩形以显示其在大图像中的外观。目前,我正在使用以下代码在大图像中将矩形放大。

Rectangle ConvertToLargeRect(Rectangle smallRect, Size largeImageSize, Size smallImageSize)
{
    double xScale = (double)largeImageSize.Width / smallImageSize.Width;
    double yScale = (double)largeImageSize.Height / smallImageSize.Height;
    int x = (int)(smallRect.X * xScale + 0.5);
    int y = (int)(smallRect.Y * yScale + 0.5);
    int right = (int)(smallRect.Right * xScale + 0.5);
    int bottom = (int)(smallRect.Bottom * yScale + 0.5);
    return new Rectangle(x, y, right - x, bottom - y);
}

更新: enter image description here enter image description here

1 个答案:

答案 0 :(得分:0)

我将使用以下方法:

  • TranslatePictureBoxSelectedRectangleToImage
    在图片框上平移选定的矩形以在图像上进行坐标。

  • TranslateImageSelectedRectangleToPictureBox
    将图像框上的选定矩形转换为图片框上的坐标。

  • ScaleRectangle
    按给定的比例因子缩放矩形。

TranslatePictureBoxSelectedRectangleToImage

public RectangleF TranslatePictureBoxSelectedRectangleToImage(PictureBox p, 
    RectangleF pictureBoxSelectedRectangle)
{
    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 pictureBoxSelectedRectangle;
    var cx = (float)p.Image.Width / (float)imageRect.Width;
    var cy = (float)p.Image.Height / (float)imageRect.Height;
    var r2 = pictureBoxSelectedRectangle;
    r2.Offset(-imageRect.X, -imageRect.Y);
    return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
}

TranslateImageSelectedRectangleToPictureBox

public RectangleF TranslateImageSelectedRectangleToPictureBox(PictureBox p, 
    RectangleF imageSelectedRectangle)
{
    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 imageSelectedRectangle;
    var cx = (float)p.Image.Width / (float)imageRect.Width;
    var cy = (float)p.Image.Height / (float)imageRect.Height;
    var r2 = new RectangleF(imageSelectedRectangle.X / cx, imageSelectedRectangle.Y / cy,
        imageSelectedRectangle.Width / cx, imageSelectedRectangle.Height / cy);
    r2.Offset(imageRect.X, imageRect.Y);
    return r2;
}

ScaleRectangle

public RectangleF ScaleRectangle(RectangleF r, float c)
{
    return new RectangleF(r.X * c, r.Y * c, r.Width * c, r.Height * c);
}

示例

使用以上方法并假设以下条件:

  • 您有image1的原始大小和image2,它是image1的程序调整大小版本,缩放比例为c。 (这表示c = (float)image2.Width/(float)image1.Width。)
  • 您正在以缩放模式在图片框中显示image2

问题1-将r1作为picureBox1上的选定矩形,image1上的矩形大小和位置是什么?

第一种方法显示了如何将图片框上的r1转换为image2上的矩形。要将其转换为image1上的矩形,因为您知道用于从image1创建image2的缩放因子,因此将相同的缩放因子应用于第一种方法的结果就足够了:

//First convert rectangle of pictureBox1 to rectangle of image2
var r2 = TranslatePictureBoxSelectedRectangleToImage(pictureBox1, r1);

//Then convert rectangle of image2 to rectangle of image1
var result = ScaleRectangle(r2, 1f/c);

问题2-以r1作为image1上的选定矩形,pictureBox1上的矩形大小和位置是什么?

第二种方法显示了如何将r1上的image2转换为pictureBox1上的矩形。要从image1上的矩形进行转换,因为您知道用于从image1创建image2的缩放因子,所以在r1上应用相同的缩放因子就足以在{{1}上获得矩形},然后使用第二种方法:

image2