写真表示アプリを作成しており、写真のズームを実装したいと考えています。ScrollViewer を作成し、そこに Image を配置しました。それはすべて箱から出して動作します。ズーム ジェスチャを実行すると、画像が拡大されます。次に実装したいのは、ズーム ジェスチャの開始時に画像の高解像度バージョンを読み込み、読み込まれたときに Image コントロールのビットマップを動的に交換することです。ユーザーがジェスチャーを続けてズームインし続け、より詳細な画像を表示できるように、シームレスに実行したいと考えています。これを達成するための最良のアプローチは何ですか?これは私が現在持っているコードです。私のコードの問題は、 Image.Source が置き換えられると、ジェスチャーが中断され、写真が元のサイズにリセットされることです。ScrollViewer ZoomFactor を変更しても、イメージが置き換えられるときにリセットされるように見えるため、役に立ちません。最初は null を返しますが、低解像度モードで「ファイル」から画像の読み込みを開始し、読み込みが終了すると OnPropertyChanged("Image") を呼び出す Image プロパティを持つ DataModel があります。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);
}
}
}
既に述べたように、このコードの問題は、ジェスチャが中断され、新しい画像が正しい位置にサイズ変更/スクロールされないことです。ユーザー エクスペリエンスはシームレスではありません。これを解決する方法についての提案をありがとう。