加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows-8 – 在执行缩放手势时替换ScrollViewer中的图像

发布时间:2020-12-14 02:16:57 所属栏目:Windows 来源:网络整理
导读:我正在创建一个照片查看应用程序,我想实现缩放图片.我创建了一个ScrollViewer并在那里放置了一个 Image.这一切都是开箱即用的.我可以做一个缩放手势,它放大图片.现在,我想要实现的下一件事是在缩放手势开始时加载图片的高分辨率版本,并在加载时动态交换Image
我正在创建一个照片查看应用程序,我想实现缩放图片.我创建了一个ScrollViewer并在那里放置了一个 Image.这一切都是开箱即用的.我可以做一个缩放手势,它放大图片.现在,我想要实现的下一件事是在缩放手势开始时加载图片的高分辨率版本,并在加载时动态交换Image控件中的位图.我希望它无缝地发生,以便用户可以继续手势并继续放大并查看更详细的图片.
实现这一目标的最佳方法是什么?
这是我目前拥有的代码.我的代码的问题是,当替换Image.Source时,我的手势被中断,照片被重置为原始大小.更换ScrollViewer ZoomFactor没有帮助,因为它似乎在更换图像时被重置.
我有一个带有Image属性的DataModel,它最初返回null但是在低分辨率模式下从’file’开始加载图片,并在加载完成时调用OnPropertyChanged(“Image”).调用LoadFullImage()加载完整分辨率版本并在完成时调用OnPropertyChanged(“Image”).

以下是DataModel.cs的摘录:

public async Task LoadFullImage()
    {
        loadFullImageTask = UpdateImage(0);
        await loadFullImageTask;
    }

    public ImageSource Image
    {
        get
        {
            if (fullImage != null)
            {
                return fullImage;
            }
            else if (image != null)
            {
                return image;
            }
            else
            {
                Task loadImageTask = UpdateImage(768);

                return null;
            }
        }
    }

    public bool FullImageLoading
    {
        get { return (this.loadFullImageTask != null) && (!this.loadFullImageTask.IsCompleted); }
    }

    public bool FullImageLoaded
    {
        get { return this.fullImage != null; }
    }

这是我的MainPage.xaml:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <ScrollViewer x:Name="imageViewer" HorizontalAlignment="Stretch" HorizontalScrollBarVisibility="Visible" VerticalAlignment="Stretch" MinZoomFactor="1" ZoomMode="Enabled" ViewChanged="imageViewer_ViewChanged">
        <Image x:Name="image" Margin="0,0" Stretch="Uniform" Source="{Binding Image}" />
    </ScrollViewer>
</Grid>

这是我的MainPage.xaml.cs:

protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        FileOpenPicker filePicker = new FileOpenPicker();
        filePicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
        filePicker.FileTypeFilter.Add(".jpg");
        StorageFile file = await filePicker.PickSingleFileAsync();

        data = new DataModel(file);
        imageViewer.DataContext = data; 
    }

    private async void imageViewer_ViewChanged(object sender,ScrollViewerViewChangedEventArgs e)
    {
        ScrollViewer imageViewer = (ScrollViewer)sender;

        if (imageViewer.ZoomFactor > 1)
        {
            if (!data.FullImageLoaded && (!data.FullImageLoading))
            {
                int oldHeight = ((BitmapImage)data.Image).PixelHeight;
                int oldWidth = ((BitmapImage)data.Image).PixelWidth;
                double oldHOffset = imageViewer.HorizontalOffset;
                double oldVOffset = imageViewer.VerticalOffset;

                await data.LoadFullImage();

                int newHeight = ((BitmapImage)data.Image).PixelHeight;
                int newWidth = ((BitmapImage)data.Image).PixelWidth;

                float ratio = (float)oldHeight / (float)newHeight;
                imageViewer.MaxZoomFactor = imageViewer.MaxZoomFactor * ratio;
                imageViewer.MinZoomFactor = imageViewer.MinZoomFactor * ratio;
                imageViewer.ZoomToFactor(imageViewer.ZoomFactor * ratio);
                //imageViewer.ScrollToHorizontalOffset(oldHOffset / ratio);
                //imageViewer.ScrollToVerticalOffset(oldVOffset / ratio);
            }
        }
    }

正如我已经提到的,此代码的问题在于手势被中断并且新图像未调整大小/滚动到正确位置,用户体验不是无缝的.
感谢您提供有关如何解决此问题的任何建议.

解决方法

我不打算为你编写这段代码,因为它太多了,但是这里是步骤:

>图像需要将ScaleTransform应用于其RenderTransform属性.当用户捏或伸展时,您将使用它来使其“缩放”.
>使用操纵事件检测捏合手势;如果它可以帮助您减少一些代码,您甚至可以仅过滤捏手势.这些事件将是最可靠的.
>操纵事件将返回正在发生的夹点或拉伸的数量,这需要与您在数字1中应用于图像的ScaleTransform的缩放量相对应.
>在代码隐藏中,您可以创建一个指向并从服务器加载图像的BitmapImage.加载后,您可以替换用户正在收集的图像源.除非高分辨率图像是兆字节,否则这对用户几乎是无缝的.不要那样做.

请注意,我的步骤不包括ScrollViewer. ScrollViewer当然可以包装图像,但工作本身是作为Image本身的一部分完成的.

我也可能会指向您可能想要窃取某些逻辑的MultiScaleImage控件,以便做到最好:http://msdn.microsoft.com/en-us/library/system.windows.controls.multiscaleimage%28v=vs.95%29.aspx

还有一件事.使用DeepZoom可以很容易地完成此操作.由于它尚未在XAML中提供,因此并不意味着您无法利用WebView来实现此目的.它将为您提供预先构建的,疯狂可扩展(和免费)的解决方案.但选择权在你手中.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读