none
WPF 画图表时很卡,如何处理呢? RRS feed

  • 问题

  • 如下图,在WPF里面继承FrameworkElement,然后重写OnRander,使用GDI和BitMap进行图表绘制,发现刷新时比较卡,调试跟踪时OnRander使用时间大约50毫秒,但是快速刷新时就很卡。不知道有什么办法解决?

    OnRander函数:图表的数据大小是2000个点,见蓝色线,在窗体后台用this.bitmap.InvalidateVisual();进行刷新

            protected override void OnRender(DrawingContext dc)
            {
                
                //  if (bitmap == null)
                {
                    //获取系统DPI
                    using (GDI.Graphics graphics = GDI.Graphics.FromHwnd(IntPtr.Zero))
                    {
                         dpiX = graphics.DpiX;
                         dpiY = graphics.DpiY;
                    }

                    this.width = (int)RenderSize.Width;
                    this.height = (int)RenderSize.Height;
                    this.bitmap = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormats.Bgr24, null);
                    RectSize = new GDI.Size(width, height);
                    GDI.Rectangle Scanrect = new GDI.Rectangle(new GDI.Point(),RectSize);
             
                    this.bitmap.Lock();
                    using (GDI.Bitmap backBufferBitmap = new GDI.Bitmap(width, height,
                   this.bitmap.BackBufferStride, GDI.Imaging.PixelFormat.Format24bppRgb,                                                                                                                                                 
                   this.bitmap.BackBuffer))
                    {
                        using (GDI.Graphics backBufferGraphics = GDI.Graphics.FromImage(backBufferBitmap))
                        {
                            backBufferGraphics.SmoothingMode = GDI.Drawing2D.SmoothingMode.HighSpeed;
                            backBufferGraphics.CompositingQuality = GDI.Drawing2D.CompositingQuality.HighSpeed;
           
                            backBufferGraphics.Clear(GDI.Color.FromArgb(BackGroundColor.A, BackGroundColor.R, BackGroundColor.G, BackGroundColor.B));
                            //绘制表格样式 以及数据线
                            GdiDrawGrapshicesLine( backBufferGraphics, Scanrect, MinRadScalePix, YradBottomValueTemp, YradTopValueTemp, XradLeftValueTemp, XradRightValueTemp);
                            backBufferGraphics.Flush();
                        }
                    }
                    this.bitmap.AddDirtyRect(new Int32Rect(0, 0, width, height));
                    this.bitmap.Unlock();

                   
                }
                dc.DrawImage(bitmap, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
                GridInitDone = true;
                base.OnRender(dc);
            }

    2017年12月6日 7:23

全部回复

  • Hi,

    请从下面几个方面考虑优化你的程序。

    你的程序的性能瓶颈是快速渲染一个bitmap。

    1. 适当降低刷新频率;

    2. 可以考虑减少数据点的渲染;对数据进行一定的预处理;

    3. 考虑异步刷新,或者预先缓存的bitmap;当数据经常变化时,建议使用多个 DrawingVisual 对象;

    4. 虽然WriteableBitmap是高性能的,但是分配一个新的位图是昂贵的, 如果您可以重复使用相同的位图,则可以通过清除或绘制现有内容来获得性能提升;这里你可以考虑使用WPF的绘图API DrawGeometry();

    5. 尝试使用WPF Toolkit的System.Windows.Controls.DataVisualization.Charting,绑定实现INotifyPropertyChanged 接口的ObservableCollection。

    https://stackoverflow.com/questions/8713864/high-performance-graphics-using-the-wpf-visual-layer

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年12月14日 2:08
    版主
  • 1. 使用OxyPlot,避免操作Bitmap:   http://www.oxyplot.org/

    2. Use the geared LiveCharts:https://lvcharts.net/App/examples/v1/wpf/Performance%20Tips

    3. 直接Direct2D(GDI/GDI+效率有限),看看高手是怎么用的:https://microsoftdwayneneed.codeplex.com/releases/view/102650

    2017年12月18日 1:34