Non-smooth DoubleAnimation

本文关键字:DoubleAnimation Non-smooth | 更新日期: 2023-09-27 18:20:45

我使用DoubleAnimation来放大和平移地图。我的地图是一幅分辨率极高的图像(15000 x 8438)。问题是,第一次缩放动画非常不流畅,第二次效果越来越好,以此类推。我如何使动画更流畅,或者在执行之前兑现图像或动画,或者使用其他形式的动画?

我的代码:

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);
    }
}
}

Non-smooth DoubleAnimation

我没有尝试过你的动画方法,我试图实现我自己的逻辑。

首先,我的灵感来自Picasa使用的缩放动画。因此,我尝试实现类似类型的动画,这在我的core2duo处理器上运行良好,图像大小为10000x5000,没有任何延迟。这种方法消耗了大量内存,但当我将我的内存使用情况与Picasa ImageViewer进行比较时,它几乎是一样的。这种方法可能会增加应用程序的加载时间,但这是可以处理的,在这里不是问题。

这是我使用过的主窗口网格的代码。

<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>

按钮点击事件代码

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);
            }
        });
}

此代码中的注释行是一个平滑动画的二次方程,用于动画的加速度和加速度。在[0-100]的范围内,计算用于在2.5处开始缩放0.2和一半并且在0.2处停止的根。如果你想创建完全自定义的动画,你可以使用WolframAlpha来检查你的动画图。但简单的方法是使用简单的控制语句来控制动画。

此代码仅用于缩放您的图像,您的方法与缩小类似。

你研究过微软的DeepZoom技术吗?http://msdn.microsoft.com/en-us/library/cc645050(v=vs.95).aspx#deep_zoom_examples

由于您没有显示任何XAML,我将从最基本的角度尝试-尝试使用RenderOptions.BitmapScalingMode="LowQuality"对您的图像元素进行缩放,如下所示:

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

请注意,只有当您的目标是.NET 3.0-3.5时,这才是实际的。因为从.NET4.0开始,"低质量"设置已设置为默认设置,因此无需显式指定。但是,如果您的缩放动画仍然不稳定,您可以尝试将此默认缩放比例从LowQuality更改为更低的NearestNeighbor,根据文档:

当使用软件光栅化器时,提供了优于低质量模式的性能优势。此模式通常用于放大位图。

此外,由于您即将显示质量有所损失的大图像,因此最好在图像或其父元素上指定UseLayoutRounding="True"以提高图像质量。

您想要使用缓存的合成。渲染贴图,但将BitmapCache指定给CacheMode属性,并将RenderAtScale设置为大于1的值。如果将地图放大5倍,则应使用具有此值的RenderAtScale,因为它会缓存用于此类型缩放的图像。这可能导致更高的内存消耗,但可能使滚动变得平滑。

此外,诺洛纳尔可能是对的。您可能需要为图像创建mipmaps,并提供平铺渲染,以部分加载看到的平铺,因为您的图像非常大。