gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 17:54:01 24 4
gpt4 key购买 nike

我正在创建一个照片查看应用程序,我想实现图片的缩放。我创建了一个 ScrollViewer 并在那里放置了一个图像。这一切都是开箱即用的。我可以做一个缩放手势,它会放大图片。现在,我要实现的下一件事是在缩放手势开始时加载图片的高分辨率版本,并在加载时动态交换 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,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 属性。当用户捏或拉伸(stretch)时,您将使用它来使其“缩放”。
  • 使用 Manipulation 事件检测捏合手势;如果它可以帮助您减少一些代码,您甚至可以仅过滤到捏合手势。这些事件将是最可靠的。
  • Manipulation 事件将返回发生了多少收缩或拉伸(stretch),这需要与您在数字 1 中应用到图像的 ScaleTransform 的缩放程度相对应。
  • 在代码隐藏中,您可以创建一个 BitmapImage 指向并从服务器加载图像。加载后,您可以替换用户正在捏的图像的来源。除非高分辨率图像是数兆字节,否则这对用户来说几乎是无缝的。不要那样做。

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

    我还可以为您指出 MultiScaleImage为了做到最好,您可能想从中窃取一些逻辑的控件: http://msdn.microsoft.com/en-us/library/system.windows.controls.multiscaleimage%28v=vs.95%29.aspx

    还有一件事。这可以通过 DeepZoom 轻松完成。由于它在 XAML 中尚不可用,这并不意味着您不能利用 WebView 来完成此操作。它将为您提供一个预先构建的、可疯狂扩展(且免费)的解决方案。但选择权在你。

    关于windows-8 - 在执行缩放手势时替换 ScrollViewer 中的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14495878/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com