Панорамирование и Изображение Масштабирования

Я хочу создать простую программу просмотра изображений в WPF, который включит пользователю к:

  • Панорамирование (мышью, перетаскивающей изображение).
  • Масштабирование (с ползунком).
  • Покажите оверлейные программы (прямоугольный выбор, например).
  • Покажите исходное изображение (с полосами прокрутки в случае необходимости).

Можно ли объяснить, как сделать это?

Я не нашел хороший образец в сети. Я должен использовать ViewBox? Или ImageBrush? Мне нужен ScrollViewer?

123
задан ASh 24 October 2019 в 12:37
поделиться

5 ответов

Я решил эту проблему, поместив изображение в рамку с его свойством ClipToBounds, установленным в True. RenderTransformOrigin на изображении затем устанавливается на 0,5,0,5, поэтому изображение начнет масштабироваться по центру изображения. Для RenderTransform также устанавливается TransformGroup, содержащая ScaleTransform и TranslateTransform.

Затем я обработал событие MouseWheel на изображении для реализации масштабирования

private void image_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var st = (ScaleTransform)image.RenderTransform;
    double zoom = e.Delta > 0 ? .2 : -.2;
    st.ScaleX += zoom;
    st.ScaleY += zoom;
}

Для обработки панорамирования первое, что я сделал, было обработало событие MouseLeftButtonDown на событии Чтобы сохранить изображение и записать его местоположение, я также сохраняю текущее значение TranslateTransform, которое обновляется для реализации панорамирования.

Point start;
Point origin;
private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    image.CaptureMouse();
    var tt = (TranslateTransform)((TransformGroup)image.RenderTransform)
        .Children.First(tr => tr is TranslateTransform);
    start = e.GetPosition(border);
    origin = new Point(tt.X, tt.Y);
}

Затем я обработал событие MouseMove, чтобы обновить TranslateTransform.

private void image_MouseMove(object sender, MouseEventArgs e)
{
    if (image.IsMouseCaptured)
    {
        var tt = (TranslateTransform)((TransformGroup)image.RenderTransform)
            .Children.First(tr => tr is TranslateTransform);
        Vector v = start - e.GetPosition(border);
        tt.X = origin.X - v.X;
        tt.Y = origin.Y - v.Y;
    }
}

Наконец, don ' не забудьте отпустить захват мыши.

private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    image.ReleaseMouseCapture();
}

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

110
ответ дан 24 November 2019 в 01:11
поделиться

Мой образец London Underground делает это, хотя с картой, а не со статическим изображением.

1
ответ дан 21 September 2019 в 04:25
поделиться
  • Панорамирование: поместите изображение внутрь холста. Реализуйте события Mouse Up, Down и Move для перемещения свойств Canvas.Top, Canvas.Left. Когда вниз, вы помечаете isDraggingFlag в true, когда вверх, вы устанавливаете флаг в false. На ходу вы проверяете, установлен ли флаг, если вы смещаете свойства Canvas.Top и Canvas.Left на изображении внутри холста.
  • Масштаб: Привязка ползунка к масштабному преобразованию холста
  • Показать наложения: добавьте дополнительные холсты без фона поверх холста, содержащего изображение.
  • показать исходное изображение: управление изображением внутри ViewBox
9
ответ дан 24 November 2019 в 01:11
поделиться

Попробуйте этот элемент управления масштабированием: http://wpfextensions.codeplex.com

Использование элемента управления очень просто, ссылка на сборку wpfextensions:

<wpfext:ZoomControl>
    <Image Source="..."/>
</wpfext:ZoomControl>

Полосы прокрутки не поддерживается в данный момент. (Это будет в следующем выпуске, который будет доступен через одну или две недели).

10
ответ дан 24 November 2019 в 01:11
поделиться

Ответ был опубликован выше, но не был полным. вот завершенная версия:

XAML

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MapTest.Window1"
x:Name="Window"
Title="Window1"
Width="1950" Height="1546" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Controls="clr-namespace:WPFExtensions.Controls;assembly=WPFExtensions" mc:Ignorable="d" Background="#FF000000">

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="52.92"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Border Grid.Row="1" Name="border">
        <Image Name="image" Source="map3-2.png" Opacity="1" RenderTransformOrigin="0.5,0.5"  />
    </Border>

</Grid>

Code Behind

using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace MapTest
{
    public partial class Window1 : Window
    {
        private Point origin;
        private Point start;

        public Window1()
        {
            InitializeComponent();

            TransformGroup group = new TransformGroup();

            ScaleTransform xform = new ScaleTransform();
            group.Children.Add(xform);

            TranslateTransform tt = new TranslateTransform();
            group.Children.Add(tt);

            image.RenderTransform = group;

            image.MouseWheel += image_MouseWheel;
            image.MouseLeftButtonDown += image_MouseLeftButtonDown;
            image.MouseLeftButtonUp += image_MouseLeftButtonUp;
            image.MouseMove += image_MouseMove;
        }

        private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            image.ReleaseMouseCapture();
        }

        private void image_MouseMove(object sender, MouseEventArgs e)
        {
            if (!image.IsMouseCaptured) return;

            var tt = (TranslateTransform) ((TransformGroup) image.RenderTransform).Children.First(tr => tr is TranslateTransform);
            Vector v = start - e.GetPosition(border);
            tt.X = origin.X - v.X;
            tt.Y = origin.Y - v.Y;
        }

        private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            image.CaptureMouse();
            var tt = (TranslateTransform) ((TransformGroup) image.RenderTransform).Children.First(tr => tr is TranslateTransform);
            start = e.GetPosition(border);
            origin = new Point(tt.X, tt.Y);
        }

        private void image_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            TransformGroup transformGroup = (TransformGroup) image.RenderTransform;
            ScaleTransform transform = (ScaleTransform) transformGroup.Children[0];

            double zoom = e.Delta > 0 ? .2 : -.2;
            transform.ScaleX += zoom;
            transform.ScaleY += zoom;
        }
    }
}

У меня есть пример полного проекта wpf с использованием этого кода на моем веб-сайте: Запишите приложение для заметок .

43
ответ дан 24 November 2019 в 01:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: