WPF 使用漸變色在繪圖中靈活應用


更新於2020年11月3日

如果將圖像的大小限制於普通1080P屏幕下,並配合調度器終端更新。可以實現2*2像素大小的方塊。也就是【1010*1920】的大小,960*505=484,800可控制像素塊

其中繪圖方式使用task等待,不過沒有什么太大的改變。

即便是每10毫秒更新一豎條也不會卡。

 

代碼上沒有太多改變

  public override  Task<bool> Draw2()
        {
            TaskCompletionSource<bool> tcp = new TaskCompletionSource<bool>();
            GeometryGroup gp = null;

            using (var dc = RenderOpen())
            {
                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)));
                }
                gp.Freeze();
                var pen = DrawSetting.Instance.DrawPen;
                pen.Freeze();
                SetLinerColor();
                dc.DrawDrawing(new GeometryDrawing(lgb, pen, gp));
                tcp.SetResult(true);
             
            }
          
            return tcp.Task;
        }
        public LinearGradientBrush lgb = new LinearGradientBrush() { StartPoint = new Point(0.5, 0), EndPoint = new Point(0.5, 1) };
     
        public void SetLinerColor()
        {
            lgb.GradientStops.Clear();  
            for (double y = 0; y < 1.0;)
            {
                var color = DrawSetting.Instance.GetColorBrush();
                lgb.GradientStops.Add(new GradientStop(color, y));
                lgb.GradientStops.Add(new GradientStop(color, y += (RectHeight / DrawHeight)));
            }
          
        }
        public void SetLinerColor(int index,Color color)
        {
            lgb.GradientStops[index].Color = color;
            lgb.GradientStops[index%2==0?index+1:index-1].Color = color;
        }

 

更新鼠標坐標的位置為黑色

  int size = 2;
        private async  void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            List<DrawRectVisual> ld = new List<DrawRectVisual>();
            List<Task> lt = new List<Task>();
            for (int x = 0; x < 1920; x+= size)
            {
                for (int y = 0; y < this.ActualHeight; y += (int)ActualHeight)
                {
                    var item = new DrawRectVisual(x, y, size, 1010, size, size);
                    await item.Draw2();
                    await draw.Dispatcher.BeginInvoke(new Action(() => draw.AddVisual(item)),DispatcherPriority.Background);      
                }
            }
            this.MouseMove += MainWindow_MouseMove;
        }
        private void MainWindow_MouseMove(object sender, MouseEventArgs e)
        {
            var point = e.GetPosition(draw);
            int x = (int)point.X / size;
            int y = ((int)point.Y/ size) *2;
            (draw.Visuals[x] as DrawRectVisual).SetLinerColor(y, Colors.Black);
            Console.WriteLine($"鼠標:{point} 轉換后{x}:{y}");
        }

 

 

**************************************

文本銜接使用DrawingVisual繪圖

效果圖

漸變色可以將多個顏色組合在一塊,形成漸變色。

不過當顏色組合非常有規律時,就不是漸變色的變現形式了。

例如【0 0.25, 0.25 0.5, 0.5 0.75 ,0.75 1】每兩個一組,就會會變成獨立的顏色塊。

利用這個特性,我們可以不必使用上文中第二種方式(每一個矩形一個顏色,相當於繪制了大量獨立的矩形塊),使用線組合的矩形就可以模擬獨立矩形塊了。

 

比如說簡單的畫一個圓

應用漸變色的算法

  public LinearGradientBrush lgb = new LinearGradientBrush() { StartPoint=new Point(0.5,0),EndPoint= new Point(0.5, 1) };//垂直拜訪
        

        public void SetLinerColor()
        {
            lgb.GradientStops.Clear();
            for (double y = 0; y < 1.0;)
            {
                var color = DrawSetting.Instance.GetColorBrush();
                lgb.GradientStops.Add(new GradientStop(color, y));
                lgb.GradientStops.Add(new GradientStop(color, y += (RectHeight / DrawHeight)));
            }
        }

繪圖時直接用lgb即可,其次再往后修改顏色不用重新繪制圖形,只用修改顏色即可

 

簡單寫的小算法,不一定什么情況下都好使。

如果哪位大佬能給改改算法,那就更好了,腦子轉不過來了...具體是XY位置確認某組顏色的算法..

圓的算法

其中

圓的算法是極坐標算法

20是每組矩形【內部矩形】的數量,寬10,高200,一個矩形上到下排列20個

80是橫向排列的最大數量,橫向80個,總共3行,共240組。

d為Y坐標對20取商數,即為是在第幾行。

k為是第某組的第幾個,或者可以用【余數】

n為第幾組矩形

xa為xy坐標轉到具體每組的算法,2N+1,每組共40個顏色,每兩個一對,(0,1)(2,3)(4,5)(6,7)。。。類推,這個公式應該還可以用別的方式。

 

 

  for (int j = 2; j < 15; j++)
            {
                for (int i = 0; i <= 360; i++)
                {
                    var ra = i * 3.14 / 180;
                    int x1 = (int)(40 + (j * Math.Cos(ra)));
                    int y1 = (int)(40 + (j * Math.Sin(ra)));
                    if (!PointList.Contains(new Point(x1, y1)))
                    {
                        PointList.Add(new Point(x1, y1));
                        //await Task.Delay(30);
                    }

                }
            }
            foreach (var item in PointList)
            {
                var x = (int)item.X;
                var y = (int)item.Y;
                var d = y / 20;
                var k = 20 - ((d + 1) * 20 - y);
                var n = (d) * 80 + x;
                var xa = 2 * k + 1;
                (draw.Visuals[n] as RectByLineDrawVisual).lgb.GradientStops[y == 0 ? 0 : xa - 1].Color = Colors.Transparent;
                (draw.Visuals[n] as RectByLineDrawVisual).lgb.GradientStops[y == 0 ? 1 : xa].Color = Colors.Transparent;
                await Task.Delay(3);
            }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM