我正在开发一款类似游戏的应用程序,它有多达千种形状(椭圆和线条),不断变换为60fps.阅读了一篇关于渲染许多移动形状的优秀文章后,我使用自定义Canvas后代实现了这一点,该后代覆盖OnRender了通过a进行绘制DrawingContext.虽然CPU使用率很高,但性能非常合理.
然而,文章表明,不断移动形状的最有效方法是使用大量DrawingVisual实例而不是OnRender.不幸的是,虽然它没有解释为什么在这种情况下应该更快.
以这种方式改变实现并不是一件小事,所以我想在决定进行切换之前了解原因以及它们是否适用于我.为什么这种DrawingVisual方法会导致CPU使用率低OnRender于此方案中的方法?
我正在编写一个WPF图像查看器,显示一个图像网格.由于性能低下,我感到困惑:即使是一个11 x 11的网格,也会让VM在长时间内没有响应,缓慢而缓慢.即使在功能强大的主机上也能表现得非常活泼.
该程序基于SO WPF中的设计:在网格中安排集合项:ItemsControl绑定到Items,一个ObservableCollection.每个Item包含一个文件系统绝对URI.ItemsControl的DataTemplate包含一个Image元素,其Source绑定到URI.
似乎问题不能是磁盘(SSD),内存(8GB VM,24GB主机)或CPU(i750).此外,大部分工作都是由WPF完成的,因此我甚至不能在我的代码中找到问题:我的代码只是将URI(即图像的路径,而不是图像)加载到集合中并快速返回.然后有一个等待,WPF显示图像.
我能想到的唯一问题是图像处理 - WPF缩小比例.但即使在拥有"足够好"的5850 ATI Radeon HD卡的主机上,性能也不是很好.
所以,我的问题是:如何在WPF上显示图像更加"活泼"?
编辑:图像是从HD m2ts视频捕获的1920x1080 22位HD JPEG.我尝试将它们(使用FFmpeg)预缩放到'ega'640x350.有是提高性能,但FFmpeg的按比例缩小的图像看起来比WPF的糟糕得多.
编辑:感谢David Osborne,代码现在以x64运行.仍然低迷.
编辑真正改善了这种情况的是MatějZábský所谓的scalling图像:降低分辨率.为了未来读者的利益:
fullPath = new Uri(path, UriKind.Absolute);
BitmapImage smallerBitmapImage = new BitmapImage();
smallerBitmapImage.BeginInit();
smallerBitmapImage.DecodePixelWidth = (int) (theWidthOfTheGrid / theNumberOfColumns);
smallerBitmapImage.UriSource = fullPath;
smallerBitmapImage.EndInit();
FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap();
formatConvertedBitmap.BeginInit();
formatConvertedBitmap.Source = smallerBitmapImage;
formatConvertedBitmap.DestinationFormat = PixelFormats.Gray16;
formatConvertedBitmap.EndInit();
formatConvertedBitmap.Freeze();
this.ImageSource = formatConvertedBitmap;
Run Code Online (Sandbox Code Playgroud) 我试图理解为什么我的图像不够活泼,所以我构建了一个样本来测试WPF性能.我使用计时器来计算我的"显示图像"事件处理程序执行了多长时间,并使用秒表来测量图像在屏幕上显示的时间.底线:当显示100,1600,2500和3600张图像时,WPF 在我的代码完成后花了2,9,12和16秒在屏幕上显示图像.所以我感到无助:似乎我无法改进我的代码以使图像显得更快 - 我需要用WPF做点什么!
所以我的问题是:我需要做些什么来使图像显示更快?
测试设置很简单:
该窗口包含一个网格.单击"测试"按钮后,将添加行和列定义.然后将图像添加到网格的每个单元格,如下所示:
var image = new Image();
image.BeginInit();
image.Name = ImageNameFromCell(theRow, theColumn);
image.Stretch = Stretch.None;
image.HorizontalAlignment = HorizontalAlignment.Center;
image.VerticalAlignment = VerticalAlignment.Center;
RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.LowQuality);
image.EndInit();
theGrid.Children.Add(image);
Run Code Online (Sandbox Code Playgroud)
最后,将每个图像的源设置为位图:灰度图像已经缩小到估计的屏幕尺寸.位图生成如下:
var smallerBitmapImage = new BitmapImage();
smallerBitmapImage.BeginInit();
smallerBitmapImage.DecodePixelWidth = (int)(theImageWidth);
smallerBitmapImage.UriSource = theUri;
smallerBitmapImage.CacheOption = BitmapCacheOption.None;
smallerBitmapImage.EndInit();
//BitmapFrame bitmapFrame = BitmapFrame.Create(this.FullPath);
var convertedBitmap = new FormatConvertedBitmap();
convertedBitmap.BeginInit();
convertedBitmap.Source = smallerBitmapImage;
convertedBitmap.DestinationFormat = PixelFormats.Gray16;
convertedBitmap.EndInit();
convertedBitmap.Freeze();
Run Code Online (Sandbox Code Playgroud)
所以,我的智慧结束了.图像显示有明显的延迟,似乎不受我的控制.我能做什么?
我正在设计一款游戏并考虑使用WPF来制作基本游戏玩法的简单原型.
是否可以实时渲染WPF中的基本2D图形?基本图形我的意思是简单的形状,如线条,圆圈等."实时"是指基于速度,加速度等参数渲染的东西,这些参数会根据玩家输入而变化 - 我认为这意味着我可以不要使用故事板来制作动画.
谢谢