Адаптируйте область прямоугольника к другому размеру - PullRequest
0 голосов
/ 15 мая 2018

В Windows Forms я делаю полноразмерный скриншот определенного окна с определенным размером окна, сохраняю его в объект Bitmap, затем я объявляю структуру Rectangle, чтобы обрезать область этого Bitmap, потому что позже янужно манипулировать только очень определенной частью / областью скриншота ...

Чтобы упростить этот вопрос, допустим, размер окна и растрового изображения составляет 640x480, X, Y прямоугольника: 436,150 иШирина, Высота: 146 170, и то, что я обрезаю из скриншота (растровое изображение), представляет собой изображение воздушного шара.Окно - это видеоигра.

Проблема в том, что когда размер окна увеличивается, изображение всплывающего окна тоже увеличивается, что очевидно, поэтому x, y и ширина / высота моего прямоугольника для размера окна 640x480 будутне правильно захватить / обрезать все изображение воздушного шара, когда окно игры имеет больший размер ...

Мне нужно знать, как я могу рассчитать 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 голосов
/ 16 мая 2018

Возможно, вы обдумываете это, но все, что вам нужно сделать, это зафиксировать процентное изменение между исходным размером и новым размером (для 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

0 голосов
/ 16 мая 2018

Учитывая исходное изображение и прямоугольник выделения внутри его границ:

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);
0 голосов
/ 15 мая 2018

Попробуйте:

, если ширина 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);
...