我正在使用DoubleAnimation
来缩放和平移地图。我的地图是一张分辨率很高的图像(15,000 x 8,438)。问题在于,第一次变焦动画非常摇摇晃晃并且不平滑,第二次它变得越来越好等等。如何在执行动画之前使动画更流畅或者使图像或动画更新,或者使用其他形式的动画?
我的代码:
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);
}
}
}
答案 0 :(得分:4)
我没有尝试过你的动画方法,我试图实现我自己的逻辑。
首先,我受到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.2和0.5的一半,在0.2的范围内停止,在[0-100]的范围内。如果要创建完全自定义的动画,可以使用WolframAlpha检查动画图形。但简单的方法是使用简单的控制语句来控制你的动画。
此代码仅用于缩放图像,缩小的方法类似。
答案 1 :(得分:3)
您是否研究过Microsoft的DeepZoom技术(这是他们用于Bing地图的技术)? http://msdn.microsoft.com/en-us/library/cc645050(v=vs.95).aspx#deep_zoom_examples
答案 2 :(得分:3)
由于您没有显示任何XAML,我将尝试从最基本的 - 尝试使用 RenderOptions.BitmapScalingMode =“LowQuality”在您的图像元素上减少位图缩放模式,如下所示:
<Image x:Name="image1"
Source="huge-image.jpg"
Stretch="Uniform"
RenderOptions.BitmapScalingMode="LowQuality" />
请注意,这仅限于 .NET 3.0-3.5 ,因为从 .NET 4.0 开始,“LowQuality”设置已设置为默认值,因此您无需明确指定它。但是如果您的放大动画仍然动摇,您可以尝试将此默认缩放从 LowQuality 更改为更低 NearestNeighbor ,according to documentation:
...使用软件光栅化器时,与LowQuality模式相比具有性能优势。此模式通常用于放大位图。
此外,由于您要显示质量下降的大图像,最好在图像或其父元素上指定 UseLayoutRounding =“True”以提高图像质量。
答案 3 :(得分:2)
您想要使用缓存的合成。渲染地图但将BitmapCache分配给CacheMode属性并将RenderAtScale设置为大于1的值。如果放大到地图5x,则应使用具有此值的RenderAtScale,因为它会缓存此类缩放的图像。 这可能会导致更高的内存消耗,但可能会平滑滚动。
更多Nolonar可能是对的。您可能需要为图像创建mipmap,并提供图块渲染以部分加载看到的图块,因为图像非常大。