Панорамирование изображения в pictureBox не работает

Я разработал приложение Windows на С#, где у меня есть pictureBox внутри панели. Я применил в нем функции увеличения и уменьшения масштаба. Теперь я хочу, чтобы изображение внутри pictureBox панорамировалось. Я применил события mouseDown, mouseMove и mouseUp к pictureBox. Код для него:

private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
   if (pflag == 1)
   {
       dragging = true;
       start = e.Location;
   }
}

private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
    // panning code
    if (pflag == 1)
    {
        if (dragging && zoom == 1)
        {
             pictureBox2.Location = new Point(pictureBox2.Left + (e.Location.X - start.X), pictureBox2.Top + (e.Location.Y - start.Y));
        }
    }
}

private void pictureBox2_MouseUp(object sender, MouseEventArgs e)
{ 
    if (pflag == 1)
    {
        dragging = false;
    }
}

Здесь изображение панорамируется, но без контроля границ. Иногда даже изображение выходит за пределы панели при панорамировании. Что мне нужно здесь, так это то, что изображение должно перемещаться вверх, влево, вправо, вниз в соответствии с коэффициентом масштабирования, т.е. как работает полоса прокрутки, а не более того.


person Umaima B    schedule 13.02.2016    source источник


Ответы (1)


Вам не нужно беспокоиться о масштабировании, так как координаты мыши будут в порядке. Расстояние отображаемых пикселей должно быть таким же, как и расстояние, на которое перемещается курсор.

Вам также не нужна переменная dragging, если только вы не используете ее для чего-то другого.

Однако вам нужно проверить кнопку мыши во время MouseMove:

    if (pflag == 1  && e.Button == System.Windows.Forms.MouseButtons.Left  )

Обратите внимание на несколько вещей:

  • Пользователь ожидает, что место, которое он перетаскивает, останется с курсором мыши, точно так же, как пиксель, которого он касается, всегда должен перемещаться. кончиком пальца. Не удивляйте его масштабированием в зум-факторе!

  • Если вы хотите сделать это, вам нужно будет использовать коэффициент, а не добавление числа.

  • Да, полосы прокрутки будут учитывать масштаб, но подъем все равно будет остаться с помощью мыши!

Вот пример того, как установить ограничения, чтобы пользователь не зашел слишком далеко. Это немного сложно, потому что оно должно работать при увеличении или уменьшении масштаба. Однако не начинайте с недопустимых позиций и не попадайте в них во время масштабирования!

//  panning code
if ( pflag == 1 && e.Button == System.Windows.Forms.MouseButtons.Left  )
{
    {
        Rectangle panRect = new Rectangle(panel1.Location, panel1.ClientSize);
        Rectangle picRect = new Rectangle(pictureBox2.Location, pictureBox2.ClientSize);
        int newLeft = pictureBox2.Left + (e.Location.X - start.X);
        int newTop = pictureBox2.Top + (e.Location.Y - start.Y);
        int newRight = newLeft + picRect.Width;
        int newBottom = newTop + picRect.Height;

        if ((newLeft < 0 && newRight < panRect.Width)
        || (newLeft > 0 /*&& newRight > panRect.Width */)) newLeft = picRect.Left;

        if ((newTop < 0 && newBottom < panRect.Width)
        || (newTop > 0 /*&& newBottom > panRect.Height*/)) newTop = picRect.Top;

        pictureBox2.Location = new Point(newLeft, newTop);
    }
    Text = "" + pictureBox2.Location;
}

Обратите внимание на две части, которые я закомментировал! Поскольку вы не можете переместить изображение, которое меньше окна просмотра; вы можете разрешить это, удалив комментарии, но затем следует соблюдать осторожность при увеличении масштаба, чтобы переместить его вверх и оставить на ноль, поскольку он никогда не должен находиться в диапазоне положительных и также перекрываться иначе полосы прокрутки будут вести себя странно..!

person TaW    schedule 13.02.2016
comment
Я попытался обновить код в соответствии с вашим комментарием, но все еще та же проблема. На самом деле во время масштабирования я увеличиваю размер pictureBox, но размер панели остается прежним. Когда я панорамирую изображение после его масштабирования, расположение pictureBox изменяется без ограничений. Я хочу, чтобы панорамирование производилось в соответствии с размером панели плюс коэффициент масштабирования, скажем, 30. За пределами этого предела, если я панорамирую, pictureBox/image не следует перемещать. Функциональность должна быть похожа на полосу прокрутки. За пределами вертикальной и горизонтальной полосы прокрутки изображение не должно перемещаться или сдвигаться. - person Umaima B; 15.02.2016
comment
Я хочу, чтобы панорамирование производилось в соответствии с размером панели плюс коэффициент масштабирования, скажем, 30. Это не имеет смысла! Панорамирование всегда должно следовать за мышью, а не быть быстрее или убегать от нее!! Функциональность должна быть похожа на полосу прокрутки. Ну, она должна идти в другом направлении, верно? Если вы хотите ограничить его, вам просто нужно добавить его в код. Кроме того, здесь он работает нормально: он работает точно так же, как сенсорный экран, когда я перетаскиваю изображение влево, оно следует за кончиком пальца/мышью. - person TaW; 15.02.2016
comment
Не могли бы вы помочь мне с кодом, чтобы добавить ограничение? - person Umaima B; 15.02.2016
comment
Сделано, но проблема немного сложнее, чем кажется на первый взгляд. Позволить пользователю делать все, что ему заблагорассудится, кажется проще, а также вполне естественно, imo. - person TaW; 15.02.2016
comment
Это работает как чудо. Большое спасибо. Ваша помощь отлично работает для меня. - person Umaima B; 15.02.2016
comment
Если вы довольны ответом, рассмотрите возможность принятия его..! - Я вижу, что вы никогда не делали этого: Перейдите к (невидимой) галочке вверху слева, под голосованием ответа и нажмите на нее! Он становится зеленым и приносит нам обоим небольшую репутацию.. - person TaW; 15.02.2016
comment
Это решение идеально подходит для изображений одинаковой ширины и высоты. Для изображений, ширина которых больше высоты, изображение не перемещается/панорамируется вверх/вниз. Для изображений, высота которых больше ширины, изображение перемещается немного вверх, оставляя нижнюю часть контейнера (панели) пустой. Пожалуйста, не могли бы вы предоставить какие-либо предложения по этому поводу?? - person Umaima B; 15.02.2016
comment
Вероятно, это связано с тем, что ваше изображение имеет «недопустимое» положение и/или размер. Как изначально , так и при масштабировании нужно убедиться, что этого не происходит. Начните с SizeMode=Autosize, а затем при увеличении или уменьшении масштаба, т. е. с SizeMode=Zoom, обязательно сохраняйте соотношение сторон! Один способ — использовать только коэффициент, другой — прибавлять сумму к одной стороне и вычислять другую пропорционально. б>. - person TaW; 15.02.2016
comment
Использование фактора может выглядеть следующим образом: pictureBox2.Size = new Size(pictureBox2.ClientSize.Width * factor, pictureBox2.ClientSize.Height * factor); В другом решении используется список факторов и вычисляются размеры из Image.Size; это ограничит уровни масштабирования фиксированной серией, как это делает Photoshop. (Рекомендуемые) - person TaW; 15.02.2016
comment
Я обновил ваш код, добавив следующее: } Теперь все работает нормально. - person Umaima B; 16.02.2016