私は写真閲覧アプリを作成していて、画像のズームを実装したいと思います。私はScrollViewerを作成し、そこにImageを配置しました。それはすべて箱から出てきます。私はズームジェスチャーを行うことができ、それは画像にズームする。次に、実装しようとしているのは、ズームジェスチャが開始され、ロードされたときにImageコントロールのビットマップを動的にスワップするときに、画像の高解像度バージョンをロードすることです。私はそれがシームレスに起こるように、ユーザーはジェスチャーを続けてズームを続け、より詳細な画像を見ることができます。 これを達成する最良の方法は何ですか? これは私が現在持っているコードです。私のコードの問題は、Image.Sourceが置き換えられたときにジェスチャが中断され、写真が元のサイズにリセットされることです。 ScrollViewerの変更イメージが置き換えられたときにリセットされるように見えるので、ZoomFactorは役に立ちません。 私は最初にnullを返しますが、低解像度モードで 'ファイル'から画像をロードし始め、読み込みが完了したらOnPropertyChanged( "Image")を呼び出すImageプロパティを持つDataModelを持っています。 LoadFullImage()を呼び出すと、フル解像度のバージョンがロードされ、終了したらOnPropertyChanged( "Image")を呼び出します。ここでズームジェスチャーを行っているときにScrollViewerの画像を置換する
は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);
}
}
}
として、私がすでに述べたように、このコードの問題は、ジェスチャーが中断され、新しいイメージが正しいサイズにサイズ変更されない/スクロールされないことですユーザーエクスペリエンスはシームレスではありません。 これを解決するための提案をありがとう。
私は、ScrollViewerがズームジェスチャをサポートしていなかった場合、ScaleTransformによるアプローチが必要だと考えました。現在、1枚の画像で完璧に動作します。非常にスムーズにズームインできます。また、私のScrollViewerはFlipViewコントロールに含まれており、ScrollViewerコントロールとFlipViewコントロールの両方からジェスチャーがうまく機能します。必要に応じて画像を反転したりズームインしたりできます。 ScrollViewerで画像をシームレスに切り替えることは不可能だと言っていますか? – Vitaly