zoukankan      html  css  js  c++  java
  • WPF 使用DrawingVisual和DispatchFrame快速提升绘图速度

    参考资料:

    https://www.jianshu.com/p/d308641498aa

    https://zhuanlan.zhihu.com/p/37167062

    这是一个来自很久以前的代码

    通过DrawingVisual和DispatchFrame快速提升绘图速度

    代码里有两种,一种是组合线形成矩形,另外一种是直接生成矩形,两者不同就是是否可以精确控制某个矩形。

    第一种形成的矩形会比第二多很多,也不会卡。如果某些绘图,单一颜色,效果会很好。

    也可以通过变换矩形块在设置颜色也会有很多造型,或者重新编写图形。

    截图2

    最主要的是继承DrawingVisual和修改canvas。

      public class BaseCanvas : Canvas
        {
            public ObservableCollection<BaseDrawVisual> Visuals
            {
                get;
                private set;
            }
            ScaleTransform Scale;
            public BaseCanvas()
            {
                Visuals = new ObservableCollection<BaseDrawVisual>();
                Scale = new ScaleTransform();
                this.RenderTransform = Scale;
            }
            double sc = 1;
            protected override void OnMouseWheel(MouseWheelEventArgs e)
            {
               // base.OnMouseWheel(e);
               if(e.Delta>0)
                {
                    sc += 0.5;
                }
                else
                {
                    sc -= 0.5;
                }
                if (sc > 48)
                    sc = 48;
                if (sc < 0.5)
                    sc = 0.5;
                Scale.CenterX = 0;
                Scale.CenterY = 0;
                Scale.ScaleX = sc;
                Scale.ScaleY = sc;
                Console.WriteLine("sc:"+sc);
               // base.OnMouseWheel(e);
            }
            protected override Visual GetVisualChild(int index)
            {
                return Visuals[index];
            }
            protected override int VisualChildrenCount => Visuals.Count;
    
            public void AddVisual(BaseDrawVisual drawVisual)
            {
                Visuals.Add(drawVisual);
                AddVisualChild(drawVisual);
                AddLogicalChild(drawVisual);
            }
            public void DelAllVisual()
            {
                foreach (var item in Visuals)
                {
                    RemoveVisualChild(item);
                    RemoveLogicalChild(item);
                }
                Visuals.Clear();
            }
    
    
        }

    部分元素

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Media;
    
    namespace DrawCanvas
    {
        public class RectByLineDrawVisual : BaseDrawVisual //也可以直接继承DrawingVisual
        {
            public RectByLineDrawVisual()
            {
    
            }
    
    
            public RectByLineDrawVisual(double X, double Y, double width, double height, double rectW, double rectH)
            {
                this.LocationX = X;
                this.LocationY = Y;
                this.DrawWidth = width;
                this.DrawHeight = height;
                this.RectWidth = rectW;
                this.RectHeight = rectH;
    
                MaxItems = (int)(DrawHeight / RectHeight * DrawWidth / RectWidth);
                SelectItem = new List<int[]>();
            }
    
    
            public double DrawHeight { get; set; }
            public double DrawWidth { get; set; }
            public double RectHeight { get; set; }
            public double RectWidth { get; set; }
            public double LocationX { get; set; }
            public double LocationY { get; set; }
    
            public Pen DrawPen = DrawSetting.Instance.DrawPen;
    
            public override void Draw()
            {
                DrawPen.Freeze();
                using (var BaseDrawing = this.RenderOpen())
                {
                    GeometryGroup gp = new GeometryGroup();
                    gp.Children.Add(new RectangleGeometry(new Rect(LocationX, LocationY, DrawWidth, DrawHeight)));
    
                    for (double x = LocationX; x < LocationX + DrawWidth; x += RectWidth)
                    {
                        gp.Children.Add(
                          new LineGeometry(new Point(x, LocationY), new Point(x, LocationY+DrawHeight)));
                       
                    }
                    for (double y = LocationY; y < LocationY + DrawHeight; y += RectHeight)
                    {
                        gp.Children.Add(
                       new LineGeometry(new Point(LocationX, y), new Point(LocationX+DrawWidth, y)));
                    }
                    BaseDrawing.DrawDrawing(new GeometryDrawing(DrawColor, DrawPen, gp));
                }
            }
        }
    }

    主界面cs

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
    
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                //   Draw();
    
                e.Handled = true;
            }
            Random GetRandom = new Random();
            int k = 0;
            private void Draw()
            {
                draw.DelAllVisual();
                for (double i = 0; i < draw.ActualWidth; i +=100)
                {
                    for (double j = 0; j < draw.ActualHeight; j += 100)
                    {
                        //NormColor=new SolidColorBrush(Color.FromRgb((byte)GetRandom.Next(1,255), (byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255))) 
                        //draw.AddVisual(new RectByLineDrawVisual(i, j, 80, draw.ActualHeight, 5, 5));
                        draw.AddVisual(new RectDrawVisual(i, j, 100, 100, 4, 4));
                    }
                }
            }
    
            private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                // Draw();
    
            }
            private void ProcessMsgs()
            {
    
                DoEvents();
            }
            public void DoEvents()
            {
                DispatcherFrame frame = new DispatcherFrame();
                Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                    new DispatcherOperationCallback(ExitFrames), frame);
                Dispatcher.PushFrame(frame);
            }
    
            public object ExitFrames(object f)
            {
                ((DispatcherFrame)f).Continue = false;
    
                return null;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Draw();
                for (int i = 0; i < draw.Visuals.Count; i++)
                {
    
                    draw.Visuals[i].Draw();
                    if (i % 10 == 0)
                        ProcessMsgs();
                }
                //   this.IsEnabled = true;
            }
            DispatcherTimer Timer = new DispatcherTimer();
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                if (Timer.IsEnabled)
                {
                    Timer.Stop();
                    return;
                }
                Timer.Interval = TimeSpan.FromMilliseconds(50);
                Timer.Tick += Timer_Tick;
                Timer.Start();
    
            }
    
            private void Timer_Tick(object sender, EventArgs e)
            {
              Changed1();
                //Changed2();
            }
            void Changed1()
            {
                for (int i = 0; i < draw.Visuals.Count;)
                {
                    var index = GetRandom.Next(0, draw.Visuals.Count);
    
                    var item = draw.Visuals[index] as RectDrawVisual;
                    //  item.SelectItem.Clear();
                    var k = new[] { GetRandom.Next(0, 20), GetRandom.Next(0, 20) };
                    if (!item.SelectItem.Contains(k))
                        item.SelectItem.Add(k);
                    else
                        item.SelectItem.Remove(k);
                    item.SelectItemBackGround = new SolidColorBrush(Colors.Red);//new SolidColorBrush(Color.FromRgb((byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255)));
                    item.Draw();
                    ProcessMsgs();
                    Console.WriteLine(index);
                    if (i == draw.Visuals.Count - 1)
                    {
                        i = 0;
                        ProcessMsgs();
                        continue;
    
                    }
                    else
                        i++;
                }
            }
            void Changed2()
            {
                var index = GetRandom.Next(0, draw.Visuals.Count - 1);
                var item = draw.Visuals[index];
                item.DrawColor = new SolidColorBrush(Color.FromRgb((byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255)));
                item.Draw();
               // ProcessMsgs();
            }
        }

    下载代码

  • 相关阅读:
    从 React Router 谈谈路由的那些事
    js中var、let、const区别
    关于Redux到底是个什么鬼
    git 中遇到的问题
    Delphi中BCD和Currency类型
    Mscomm控件安装问题 License information for TMSComm not found.
    以前的某个程序已在安装计算机上创建挂起的文件操作,运行安装程序之前必须重新启动计算机
    win7系统安装SQLServer2000的详细步骤(图文)
    Delphi判断字符串中是否包含汉字,并返回汉字位置
    Sql Server中判断表、列不存在则创建的方法[转]
  • 原文地址:https://www.cnblogs.com/T-ARF/p/13532041.html
Copyright © 2011-2022 走看看