Геометрия масштабирования изображения - PullRequest
2 голосов
/ 14 июля 2010

Это очень связанный с программированием вопрос, но несколько не относящийся к программированию. Я выполняю масштабирование изображения в веб-приложении, и мне нужно сохранить свое изображение относительно фиксированного местоположения, даже если оно масштабируется с привязкой к верхнему левому углу. Надеюсь, что графика сделает это возможным. alt text

Идея состоит в том, что C - это фиксированное местоположение, которое я хочу сохранить в качестве источника масштабирования, а не B, которое является текущим поведением CSS. C может или не может быть в пределах фактического изображения. Таким образом, в качестве масштаба изображения B необходимо переместить относительно C. Пример: если изображение было масштабировано на 50%, то B переместилось бы на 1/2 расстояния до C. Если изображение выросло до 200% от его размера, то B отодвинуться вдвое дальше от C.

В конечном итоге ищем формулу для x & y для B с учетом местоположения C и коэффициента масштабирования для изображения. Не уверен, что размер изображения должен быть частью этого, но он у меня есть, если нужно.

Спасибо за любую помощь!

Вещи, которые я знаю:

  1. Я знаю ширину и высоту прямоугольник изображения.
  2. Я знаю смещение B от A.
  3. Я знаю смещение C от A.
  4. Я знаю масштабный коэффициент в процентах от изображения.

Ответы [ 5 ]

2 голосов
/ 14 июля 2010

По сути, вы хотите рассматривать C как источник и просто «переместить» B на величину масштабирования.Обрабатывая его как вектор от C до B и масштабируя его на соответствующую сумму, вы можете сделать это довольно легко.

newBx = Cx - (Cx - Bx) * scale;
newBy = Cy - (Cy - By) * scale;

Например, со шкалой 0,5 (50%), этостановится:

newBx = 100 - (100 - 50) * 0.5 
      = 100 - 25
      = 75                 // 1/2 the distance to C
newBy = 100 - (100 - 25) * 0.5
      = 100 - 37.5
      = 62.5               // 1/2 the distance to C

со шкалой 2 (200%):

newBx = 100 - (100 - 50) * 2 
      = 100 - 100
      = 0                  // 2x the distance to C
newBy = 100 - (100 - 25) * 2
      = 100 - 150
      = -50                // 2x the distance to C
1 голос
/ 14 июля 2010

Сначала вам нужно вычислить расстояние от B до C, затем вы просто измените его на масштаб, и именно там новый B будет относительно C:

newB = C - (C - B) * scale

Как вы хотите, чтобы координаты, это то же самое функция для х и у:

newBx = Cx - (Cx - Bx) * scale
newBy = Cy - (Cy - By) * scale

(Используемое значение шкалы - не процент, а множитель размера. Увеличение размера на 50% дает шкалу 1.5.)

0 голосов
/ 14 июля 2010

вот фрагмент кода C #, который протестирован для работы:

void Main()
{
    Application.Run(new form1());
}

public class form1 : Form
{
    static Point C = new Point(100,100);
    static Point origLocB = new Point(50,25);
    static Size origSizeB = new Size(150,100);

    Panel Rec = new Panel() 
    {
        Left = origLocB.X, 
        Top = origLocB.Y, 
        Width = origSizeB.Width, 
        Height = origSizeB.Height,
        BorderStyle = BorderStyle.FixedSingle,
    };

    NumericUpDown nud = new NumericUpDown()
    {
        Value = 1M,
        Increment = .01M,
        DecimalPlaces = 2,
        Dock = DockStyle.Bottom,
    };

    public form1()
    {
        nud.ValueChanged += NumericUpDown_ValueChanged;
        Controls.Add(nud);
        Controls.Add(Rec);
    }

    public void NumericUpDown_ValueChanged(object sender, EventArgs e)
    {
        Rec.Location = new Point(((int)((origLocB.X - C.X) * nud.Value + C.X)),
                                ((int)((origLocB.Y - C.Y) * nud.Value + C.Y)));
        Rec.Size = new Size((int)(origSizeB.Width*nud.Value),
                            (int)(origSizeB.Height*nud.Value));
    }
}

это действительно просто эхо @ Рида Ответ

0 голосов
/ 14 июля 2010

Если я понимаю проблему:

X(b) = X(c) - Width*(1/3)    
Y(b) = Y(c) - Height*(3/4)

Формула кажется достаточно простой, но ваше примерное изображение не может быть больше 133x200 (масштаб = 133%), прежде чем оно превысит Y = 0 (я полагаю, это ваш северный предел).

Если вы хотите остановить движение за пределы Y = 0 или X = 0 и вытолкнуть дальше на юг и восток, как только он достигнет любого предела, один из подходов может быть:

IIF(Height > 133, Y(b) = 0, Y(b) = Y(c) - Height*(3/4))
IIF(Width > 450, X(b) = 0, X(b) = X(c) - Width*(1/3))

Я думаю, масштаб следует преобразовать в высоту и ширину, а не использовать масштаб в качестве переменной в этих формулах, поскольку исходное изображение может быть любого размера (при условии, что они не всегда будут 100x150 для каждого образца) *

  • 1012 * Дэйв *
0 голосов
/ 14 июля 2010

Таким образом, вы хотите, чтобы точка C на изображении, которое в данный момент находится на (C_x, C_y), оставалась на той же позиции после масштабирования изображения с коэффициентом s?

Новая позиция Cскажем, C_new = (s*C_x,s*C_y).

И вы хотите переместить изображение так, чтобы C_new = C.

Что означает, что вам придется сместить B = (B_x,B_y) на (s*C_x-C_x,s*C_y-C_y), илиновый источник изображения, скажем, B_new:

B_new = (B_x + s*C_x-C_x,  B_y + s*C_y-C_y)

Так что теперь вы можете отображать масштабированное изображение в B_new --- и C должно оставаться фиксированным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...