2020年8月20日星期四

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

 

 

下载代码

WPF 使用DrawingVisual和DispatchFrame快速提升绘图速度如何选品0基础也能快速搞定Shopee斑马物联网2025年印度的数字交易市场将达1万亿美元!亚马逊新手卖家千万要规避这些常见错误!重磅!亚马逊将停止重要功能使用2017年五四青年节放假吗?2017五一高速免费吗?2017五一高速免费什么时候开始?

没有评论:

发表评论