将Rectangle的区域调整为不同的大小

时间:2018-05-15 20:04:55

标签: c# .net winforms gdi+

在Windows窗体下,我拍摄了具有特定窗口大小的特定窗口的全尺寸屏幕截图,我将其保存到Bitmap对象中,然后,我声明了一个Rectangle结构来裁剪该Bitmap的一个区域,因为后来我需要仅操纵屏幕截图的非常特定的部分/区域...

为了使这个问题更简单,我们可以说窗口和位图大小是640x480,矩形的X,Y是:436,150,宽度,高度是:146,170,我从截图(位图)裁剪的是气球图像。窗口是电子游戏。

问题在于,当窗口大小增加时,气球图像也会增加,因此对于窗口大小为640x480的矩形的x,y和宽度/高度将无法正确捕获/裁剪整个气球图像当游戏的窗口有更大的尺寸......

我需要知道如何计算我的矩形在窗口大小变化时正确裁剪气球图像所需的x,y宽度/高度。我需要调整矩形。

所以,如果这是我预定义的大小和矩形:

{ new Size(640, 480), new Rectangle(436, 150, 146, 170) }

从那以后,矩形应该具有的近似适应值在窗口大小800x600和1280x768中正确裁剪相同的等效区域,这或多或少都是这样:

{ new Size(800, 600), new Rectangle(546, 186, 186, 212) }
{ new Size(1280, 768), new Rectangle(830, 232, 240, 274) }

...只是近似值,但并不完美,因为我手动完成,因为我不确定哪种方法可以计算和自动化这种数学运算。

我希望我的问题和问题得到理解。谢谢你提前。

3 个答案:

答案 0 :(得分:1)

试试这个:

如果宽度640:

X = 436 / 640 = 0.68125 (68.125%)
W = 146 / 640 = 0.22125 (22.125%)

如果高达480:

Y = 150 / 480 = 0.3125 (31.25%)
H = 170 / 480 = 0.3541666666666666666666666667 (35.41666666666666666666666667%)

将表单的大小考虑为this.Width,将高度考虑为this.Height

decimal pX = 0.68125;
decimal pW = 0.22125;
decimal pY = 0.3125;
decimal pH = 0.3541666666666666666666666667;

Rectangle rect = new Rectangle(this.Width * pX, this.Height * pY, this.Width * pW, this.Height * pH);

答案 1 :(得分:1)

也许你过度思考它,但你需要做的就是捕获原始大小和新大小(X和Y)之间的百分比变化,然后将该百分比应用于原始属性矩形来获取新的矩形。

例如:

public static Rectangle GetNewRectangle(Size oldSize, Rectangle oldRectangle, 
    Size newSize)
{
    var percentChangeX = (double)newSize.Width / oldSize.Width;
    var percentChangeY = (double)newSize.Height / oldSize.Height;

    return new Rectangle
    {
        X = (int)(oldRectangle.X * percentChangeX),
        Y = (int)(oldRectangle.Y * percentChangeY),
        Width = (int)(oldRectangle.Width * percentChangeX),
        Height = (int)(oldRectangle.Height * percentChangeY)
    };
}

使用示例:

// Helper method to display size and rectangle properties
private static string GetDisplayValues(Size size, Rectangle rect)
{
    return $" - size: {size.Width} x {size.Height}\n" +
           $" - rect: {rect.X}, {rect.Y} : {rect.Width} x {rect.Height}\n";
}

private static void Main()
{
    var size = new Size(640, 480);
    var rect = new Rectangle(436, 150, 146, 170);                        
    Console.WriteLine($"Original:\n{GetDisplayValues(size, rect)}");

    var newSize = new Size(800, 600);
    var newRect = GetNewRectangle(size, rect, newSize);
    Console.WriteLine($"Resized:\n{GetDisplayValues(newSize, newRect)}");

    GetKeyFromUser("\nDone! Press any key to exit...");
}

<强>输出

enter image description here

答案 2 :(得分:1)

在其边界内给出源位图和选择矩形:

RectangleF SourceRect = new Rectangle(Point.Empty, SourceBitmap.Size);
Rectangle SelectionRect = new Rectangle([Point], [Size]);

SourceBitmap更改其大小时,选择矩形的新大小将使用旧大小与SourceBitmap的新大小之间的关系给出的比例因子计算:

RectangleF DestinationRect = new RectangleF(Point.Empty, InflatedBitmap.Size); 

SizeF ScaleFactor = new SizeF(DestinationRect.Width / SourceRect.Width, 
                              DestinationRect.Height / SourceRect.Height);

PointF NewPosition = new PointF(SelectionRect.X * ScaleFactor.Width, SelectionRect.Y * ScaleFactor.Height);
SizeF NewSize = new SizeF(SelectionRect.Width * ScaleFactor.Width, SelectionRect.Height * ScaleFactor.Height);

RectangleF InflatedSelection = new RectangleF(NewPosition, NewSize);

使用SourceBitmap和选择矩形,大小为:

RectangleF SourceRect = new RectangleF(0, 0, 640, 480);
RectangleF SelectionRect = new RectangleF(436, 150, 146, 170);

如果膨胀的位图大小为:

RectangleF DestinationRect1 = new RectangleF(0, 0, 800, 600);
RectangleF DestinationRect2 = new RectangleF(0, 0, 1280, 768);

比例因子为(1.25, 1.25)(2, 1.6)的夸大选择将(向下舍入):

RectangleF InflatedSelection1 = new RectangleF(545, 187, 182, 212);
RectangleF InflatedSelection2 = new RectangleF(872, 240, 292, 272);