WPF图片浏览器(为什么图像跳舞)

时间:2014-09-21 20:27:01

标签: c# wpf image stretch

我试图创建一个允许查看/缩放/移动图像的简单窗口。当我们调整大小时,它的行为开始与图像大小调整以适应窗口的行为类似。

奇怪的是,当您减小窗口的宽度时,在某个点处,图片的高度在不应该的时候开始减小,然后它会反弹到不同的位置。然而,在代码中,图像的高度保持不变,因此"某些东西"否则正在改变布局。

另一个奇怪的事情是,当你增加宽度时,图像几乎保持居中,除了它逐渐向右倾斜。

所以我的问题是:是什么让我的布局搞砸了?

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            x:Class="NaturalGroundingPlayer.ImageViewerWindow"
            x:Name="Window" Title="Image Viewer" Width="640" Height="480" SizeChanged="Window_SizeChanged">
    <Grid x:Name="LayoutRoot">
        <Canvas x:Name="ImgCanvas" ClipToBounds="True">
            <ContentControl x:Name="ImgContentCtrl" Height="300" Width="400">
                <Grid x:Name="ImgGrid">
                    <Image x:Name="ImgObject"/>
                    <Thumb x:Name="ImgThumb" Opacity="0" DragDelta="ImgThumb_DragDelta" MouseWheel="ImgThumb_MouseWheel"/>
                </Grid>
            </ContentControl>
        </Canvas>
    </Grid>
</Window>



public partial class ImageViewerWindow : Window {
    public static ImageViewerWindow Instance(string fileName) {
        ImageViewerWindow NewForm = new ImageViewerWindow();
        NewForm.LoadImage(fileName);
        NewForm.Show();
        return NewForm;
    }

    private double scale;

    public ImageViewerWindow() {
        InitializeComponent();
    }

    public void LoadImage(string fileName) {
        BitmapImage NewImage = new BitmapImage();
        NewImage.BeginInit();
        NewImage.UriSource = new Uri(fileName);
        NewImage.EndInit();
        ImgObject.Source = NewImage;
        //ImgContentCtrl.Width = NewImage.Width;
        //ImgContentCtrl.Height = NewImage.Height;
        BestFit();
    }

    private void ImgThumb_DragDelta(object sender, DragDeltaEventArgs e) {
        double ImgLeft = Canvas.GetLeft(ImgContentCtrl);
        double ImgTop = Canvas.GetTop(ImgContentCtrl);
        Canvas.SetLeft(ImgContentCtrl, (ImgLeft + e.HorizontalChange));
        Canvas.SetTop(ImgContentCtrl, (ImgTop + e.VerticalChange));
    }

    private void ImgThumb_MouseWheel(object sender, MouseWheelEventArgs e) {
        // Zoom in when the user scrolls the mouse wheel up and vice versa.
        if (e.Delta > 0) {
            // Limit zoom-in to 500%
            if (scale < 5) 
                scale += 0.1;
        } else {
            // When mouse wheel is scrolled down...
            // Limit zoom-out to 80%
            if (scale > 0.8) 
                scale -= 0.1;
        }
        DisplayImage();
    }

    private void BestFit() {
        // Set the scale of the ContentControl to 100%.
        scale = 1;

        // Set the position of the ContentControl so that the image is centered.
        Canvas.SetLeft(ImgContentCtrl, 0);
        Canvas.SetTop(ImgContentCtrl, 0);
    }

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e) {
        DisplayImage();
    }

    private void DisplayImage() {
        double RatioWidth = LayoutRoot.ActualWidth / ImgObject.Source.Width;
        double RatioHeight = LayoutRoot.ActualHeight / ImgObject.Source.Height;
        if (RatioHeight > RatioWidth) {
            ImgContentCtrl.Width = LayoutRoot.ActualWidth * scale;
            ImgContentCtrl.Height = LayoutRoot.ActualHeight * RatioHeight * scale;
        } else {
            ImgContentCtrl.Height = LayoutRoot.ActualHeight * scale;
            ImgContentCtrl.Width = LayoutRoot.ActualWidth * RatioWidth * scale;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

Sjips,你首先需要在其中放置任何图片来显示。

dkozl,确实有效,我不确定Image控件会自动尊重比例,因为我发现的演示在调整大小时并不尊重比例。简单地将此代码放在DisplayImage中即使在缩放时也能正确地重新定位。我想我比答案更接近答案了!

private void DisplayImage() {
    ImgContentCtrl.Width = LayoutRoot.ActualWidth * scale;
    Canvas.SetLeft(ImgContentCtrl, LayoutRoot.ActualWidth * (1 - scale) / 2);
    ImgContentCtrl.Height = LayoutRoot.ActualHeight * scale;
    Canvas.SetTop(ImgContentCtrl, LayoutRoot.ActualHeight * (1 - scale) / 2);
}

话虽如此,我仍然没有发现之前发生的奇怪行为......