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

    下载代码

  • 相关阅读:
    The Python Standard Library
    Python 中的round函数
    Python文件类型
    Python中import的用法
    Python Symbols 各种符号
    python 一行写多个语句
    免费SSL证书(https网站)申请,便宜SSL https证书申请
    元宇宙游戏Axie龙头axs分析
    OLE DB provider "SQLNCLI10" for linked server "x.x.x.x" returned message "No transaction is active.".
    The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "xxx.xxx.xxx.xxx" was unable to begin a distributed transaction.
  • 原文地址:https://www.cnblogs.com/T-ARF/p/13532041.html
Copyright © 2011-2022 走看看