Nonsmooth DoubleAnimation

I use DoubleAnimation to scale and pan to and from the map. My map is a huge resolution image (15,000 x 8,438). The problem is that the first time the zoom animation is very choppy and uneven, the second time it gets better and so on. How can I make my animation smoother or do some cashing of the image or animation before it is executed or, possibly, using a different form of animation?

My code is:

 namespace AnimationTest { public partial class MainWindow : Window { ScaleTransform transP; TranslateTransform trans2P; DoubleAnimation animP; DoubleAnimation animYP; DoubleAnimation animXP; TransformGroup myTransformGroupP; public MainWindow() { InitializeComponent(); transP = new ScaleTransform(); trans2P = new TranslateTransform(); myTransformGroupP = new TransformGroup(); myTransformGroupP.Children.Add(transP); myTransformGroupP.Children.Add(trans2P); animP = new DoubleAnimation(1, 20, TimeSpan.FromMilliseconds(3000)); animXP = new DoubleAnimation(0, -14000, TimeSpan.FromMilliseconds(3000)); animYP = new DoubleAnimation(0, -4000, TimeSpan.FromMilliseconds(3000)); } private void button1_Click(object sender, RoutedEventArgs e) { image1.RenderTransform = myTransformGroupP; transP.BeginAnimation(ScaleTransform.ScaleXProperty, animP); transP.BeginAnimation(ScaleTransform.ScaleYProperty, animP); trans2P.BeginAnimation(TranslateTransform.XProperty, animXP); trans2P.BeginAnimation(TranslateTransform.YProperty, animYP); } } } 
+6
source share
4 answers

I did not try your animation approach, I tried to implement my own logic for this.

At first I was inspired by the scaling animations used by Picasa . So I tried to implement this type of animation, and it works fine for me on my core2duo processor with an image size of 10000x5000 without any lag. This approach consumed a lot of memory, but when I compared my memory usage with Picasa ImageViewer , it was almost the same. This approach may increase the load time of your application, but it can be handled, not a problem.

Here is the code for the main window that I used.

 <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button Grid.Row="0" Height="30" Width="100" Content="Zoom" Click="ButtonZoom_OnClick" /> <Image RenderOptions.BitmapScalingMode="HighQuality" Stretch="Uniform" Width="100" Height="100" Grid.Row="1" Margin="30" VerticalAlignment="Center" HorizontalAlignment="Center" Source="mad1.jpg" Name="ImageMain" x:FieldModifier="private" /> </Grid> 

Copy Event Code Button

 private void ButtonZoom_OnClick(object sender, RoutedEventArgs e) { Task.Factory.StartNew(() => { var i = 0; while (i++ < 100) { var i1 = i; //var i1 = (-0.00092)*(i*i) + (0.092)*i + 0.2; Dispatcher.Invoke(new Action(() => { if (i1 < 10 || i1 > 90) { ImageMain.Height += 0.5; ImageMain.Width += 0.5; } else if (i1 < 30 || i1 > 70) { ImageMain.Height += 1; ImageMain.Width += 1; } else { ImageMain.Height += 3; ImageMain.Width += 3; } })); Thread.Sleep(30); } }); } 

The commented line in this code is a quadratic equation for smooth animation to speed up and speed up the animation. roots are calculated to start scaling at 0.2 and half at 2.5 and stop at 0.2 with a range of [0-100]. if you want to create a fully customized animation, you can use WolframAlpha to check the animation schedule. but a simple approach is to use simple control statements to control your animation.

This code is only for scaling an image, your approach will be similar for zooming out.

+4
source

Have you studied Microsoft DeepZoom technology (this is what they use for Bing Maps)? http://msdn.microsoft.com/en-us/library/cc645050(v=vs.95).aspx#deep_zoom_examples

+3
source

Since you didn’t show XAML, I’ll try the simplest thing - try reducing the bitmap scaling mode using RenderOptions.BitmapScalingMode = "LowQuality" on your image element, for example:

 <Image x:Name="image1" Source="huge-image.jpg" Stretch="Uniform" RenderOptions.BitmapScalingMode="LowQuality" /> 

Please note that this is only relevant if you are targeting .NET 3.0-3.5 starting with .NET 4.0 , the "LowQuality" parameter is already set by default, so you do not need to specify it explicitly. But if the zoom animation is still interrupted, you can try changing the default scale from LowQuality to an even lower NearestNeighbor , which according to the documentation :

... provides performance benefits in LowQuality mode when using a software rasterizer. This mode is often used to enlarge a raster image.

In addition, since you are about to display a large image with some loss of quality, it may be better to specify UseLayoutRounding = "True" on your image or its parent to improve image quality.

+3
source

You want to use a cached composition. Display your map, but assign a BitmapCache for the CacheMode property and set the RenderAtScale to a value greater than 1. If you zoom in on the 5x map, you must use RenderAtScale with this value because it caches the image for this type of zoom. This can lead to significant memory consumption, but can smooth out scrolling.

Further Nolonar may be right. You may need to create mipmaps for the image and provide fragment rendering to partially load the noticed fragments, since your image is quite large.

+2
source

Source: https://habr.com/ru/post/948535/


All Articles