Панорамирование изображений Silverlight

#silverlight-4.0

#silverlight-4.0

Вопрос:

Я работаю над приложением silverlight, и я хочу панорамировать изображение сверху, снизу, влево, вправо, как я могу панорамировать изображение.

Я использовал пиксельное шейдерирование, но мне это не удалось.

Спасибо..

Ответ №1:

Взгляните на этот пример

Вы также могли бы посмотреть на поведение наложения при перетаскивании.

Ответ №2:

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

Чтобы использовать окно:

 BitmapImage BMP = /* resolve the bitmap */;

PreviewImageWindow.Execute(BMP);
  

Код (за) для окна показан ниже.

 using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;

namespace ITIS.Controls.LinearViewer.Windows {

public partial class PreviewImageWindow : ChildWindow {

    /// <summary>See Execute</summary>
    PreviewImageWindow() {
        InitializeComponent();
    }

    private void OKButton_Click(object sender, RoutedEventArgs e) {
        this.DialogResult = true;
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e) {
        this.DialogResult = false;
    }

    static public void Execute(BitmapImage imageSource) {

        PreviewImageWindow Window = new PreviewImageWindow();

        Window.Image.Source = imageSource;

        /* don't allow the window to grow larger than the image */
        Window.MaxWidth = imageSource.PixelWidth;
        Window.MaxHeight = imageSource.PixelHeight;

        Window.Show();
    }

    private void ChildWindow_KeyDown(object sender, KeyEventArgs e) {

        if (e.Key == Key.Escape) {

            DialogResult = false;
        }
    }

    Point? _lastPoint;

    bool _isMouseDown;

    private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {

        ((Image)sender).CaptureMouse();

        _isMouseDown = true;

        ShowCursor(e.GetPosition(Canvas));

        _lastPoint = e.GetPosition((Image)sender);
    }

    private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {

        ((Image)sender).ReleaseMouseCapture();

        _isMouseDown = false;

        ShowCursor(e.GetPosition(Canvas));

        _lastPoint = null;
    }

    private void image_MouseMove(object sender, MouseEventArgs e) {

        if (_lastPoint != null) {

            Image Image = (Image)sender;

            Point CurrentPoint = e.GetPosition(Image);

            double 
                XDelta = CurrentPoint.X - _lastPoint.Value.X,
                YDelta = CurrentPoint.Y - _lastPoint.Value.Y;

            _lastPoint = null;

            if (XDelta != 0) {
                double NewLeft = Canvas.GetLeft(Image)   XDelta;
                if (NewLeft <= 0 amp;amp; NewLeft   Image.ActualWidth >= Canvas.ActualWidth) {
                    Canvas.SetLeft(Image, NewLeft);
                }
            }

            if (YDelta != 0) {
                double NewTop = Canvas.GetTop(Image)   YDelta;
                if (NewTop <= 0 amp;amp; NewTop   Image.ActualHeight >= Canvas.ActualHeight) {
                    Canvas.SetTop(Image, NewTop);
                }
            }

            _lastPoint = e.GetPosition(Image);
        }

        Point CanvasPoint = e.GetPosition(Canvas);
        ShowCursor(CanvasPoint);
    }

    private void Canvas_Loaded(object sender, RoutedEventArgs e) {

        TryDefaultImageToTop();
    }

    void TryDefaultImageToTop() {

        if (Image == null || Canvas == null) { return; }

        /* move the image up so we can focus on the road? user-friendly since we are most-likely going to look at the road, not the horizon or top - half */
        if (!_initialized) {

            _initialized = true;

            Canvas.SetTop(Image, Canvas.ActualHeight - Image.ActualHeight);
            Canvas.SetLeft(Image, (Canvas.ActualWidth - Image.ActualWidth) / 2);
        }
    }

    bool _initialized;

    private void image_Loaded(object sender, RoutedEventArgs e) {

        TryDefaultImageToTop();
    }

    private void image_MouseEnter(object sender, MouseEventArgs e) {

        imgOpenHand.Visibility = Visibility.Visible;
        imgClosedHand.Visibility = Visibility.Collapsed;

        ShowCursor(e.GetPosition(Canvas));
    }

    void ShowCursor(Point point) {

        if (_isMouseDown) {
            imgClosedHand.Visibility = Visibility.Visible;
            imgOpenHand.Visibility = Visibility.Collapsed;

            Canvas.SetLeft(imgClosedHand, point.X);
            Canvas.SetTop(imgClosedHand, point.Y);
        }
        else {
            imgClosedHand.Visibility = Visibility.Collapsed;
            imgOpenHand.Visibility = Visibility.Visible;

            Canvas.SetLeft(imgOpenHand, point.X);
            Canvas.SetTop(imgOpenHand, point.Y);
        }
    }

    private void image_MouseLeave(object sender, MouseEventArgs e) {
        imgOpenHand.Visibility = Visibility.Collapsed;
        imgClosedHand.Visibility = Visibility.Collapsed;
    }
}
  

}

XAML для окна показан ниже:

 <controls:ChildWindow 
x:Class="ITIS.Controls.LinearViewer.Windows.PreviewImageWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Background="#383838" Foreground="WhiteSmoke"    
Title="Preview" Margin="50"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
KeyDown="ChildWindow_KeyDown"    
>
<Grid x:Name="LayoutRoot" Margin="0" Cursor="None" IsHitTestVisible="True">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Canvas Cursor="None" IsHitTestVisible="True" x:Name="Canvas" Loaded="Canvas_Loaded">
        <Image Source="{Binding ImageSource}" x:Name="Image"
               Cursor="None" Loaded="image_Loaded"
               MouseLeftButtonDown="image_MouseLeftButtonDown"
               MouseLeftButtonUp="image_MouseLeftButtonUp"
               MouseMove="image_MouseMove"
               MouseEnter="image_MouseEnter"
               MouseLeave="image_MouseLeave"
               IsHitTestVisible="True"
               />
        <Image Style="{StaticResource HandOpenImage}" x:Name="imgOpenHand" 
               Visibility="Collapsed" IsHitTestVisible="False" 
               />
        <Image Style="{StaticResource HandClosedImage}" x:Name="imgClosedHand"
               Visibility="Collapsed" IsHitTestVisible="False" 
               />
    </Canvas>        
</Grid>    
  

Несколько ЗАМЕЧАНИЙ об этом коде:

  1. Пространство имен для этого окна — «ITIS.Элементы управления.LinearViewer.Windows», пожалуйста, измените пространство имен на что-то более актуальное в вашей системе.
  2. Обычным изображением курсора является Открытым способом, и когда нажата кнопка мыши, изображение меняется на Закрыто вручную
  3. Стили для изображений, которые у меня есть в глобальном словаре ресурсов всего приложения:

(Стиль ОТКРЫТОГО изображения)

 <Style TargetType="Image" x:Key="HandOpenImage">
    <Setter Property="Source" Value="/ITIS.Controls.LinearViewer.Silverlight;component/Images/HandOpen.png" />
    <Setter Property="Width" Value="16" />
    <Setter Property="Height" Value="16" />
</Style>
  

(Стиль ЗАКРЫТОГО изображения)

 <Style TargetType="Image" x:Key="HandClosedImage">
    <Setter Property="Source" Value="/ITIS.Controls.LinearViewer.Silverlight;component/Images/HandClosed.png" />
    <Setter Property="Width" Value="13" />
    <Setter Property="Height" Value="11" />
</Style>
  
  1. Этот предварительный просмотр пытается начать с фокусировки на нижней половине изображения, а не на верхней.

Надеюсь, это поможет. Мне потребовалось некоторое время, чтобы устранить некоторые раздражения.