1. 程式人生 > >CPF 入門教程 - 繪圖(四)

CPF 入門教程 - 繪圖(四)

CPF NetCore跨平臺UI框架,增加了Vlc支援跨平臺播放視訊。

 

系列教程

CPF 入門教程(一)

CPF 入門教程 - 資料繫結和命令繫結(二)

CPF 入門教程 - 樣式和動畫(三)

CPF 入門教程 - 繪圖(四)

 

一般來說是不需要自己寫繪圖程式碼的,大部分UI效果通過控制元件元素(CPF.Shapes提供基礎圖形控制元件)組合和SVG組合就可以實現。

如果需要自定義控制元件繪製特殊的控制元件,可以繼承Control或者UIElement重寫OnRender方法來繪製自己需要的效果。呼叫 Invalidate 或者在依賴屬性上設定AffectsRender來重新整理介面。

        /// <summary>
        /// 背景填充
        /// </summary>
        [UIPropertyMetadata(null, UIPropertyOptions.AffectsRender)]//屬性變化之後自動重新整理
        public ViewFill Background
        {
            get { return (ViewFill)GetValue(); }
            set { SetValue(value); }
        }

 

        protected override void OnRender(DrawingContext dc)
        {
            var s = ActualSize;

            var rect = new Rect(0, 0, s.Width, s.Height);

            var ba = Background;
            if (ba != null)
            {//填充背景
                  using (var brush = ba.CreateBrush(rect, Root.RenderScaling))
                  {
                        dc.FillRectangle(brush, rect);
                  }
             }
        }

其中Background 是 ViewFill 型別,ViewFill和Brush區別就是ViewFill和UI元素相關,可以支援相對或者絕對的效果,以及DPI的縮放。

繪圖使用DrawingContext來操作,支援常規的圖形繪製,比如線條,文字,路徑等等。

使用剪輯區域的時候需要PushClip和PopClip配對,就是當你設定一個剪輯區域,使用完了之後你需要把你這個剪輯區域刪除。可以設定多次剪輯區域,像括號一樣配對和範圍。

         dc.PushClip(rect);//設定一個剪輯區域
         //繪圖操作
         dc.DrawImage(bmp, rect, rect.......
         //..........
         dc.PopClip();

矩陣使用 

var old = dc.Transform;//獲取原來的矩陣
var eff = old;
eff.Translate(-off.X + effectOffset.X, -off.Y + effectOffset.Y);//矩陣變換
dc.Transform = eff;//應用新矩陣

//繪圖操作

dc.Transform = old;//恢復原來的

 

PathGeometry 支援WPF和SVG的path裡的字串格式資料,隱式轉換。可以組合貝塞爾曲線,圓弧,線段等等用來繪製各種複雜的圖形效果。再通過DrawingContext繪製出來

比如:

PathGeometry path="m85.33333,682.66667l853.33334,0l0,21.33333l-853.33334,0l0,-21.33333z";

 

在位圖裡繪圖

 

 using (Bitmap bmp = new Bitmap(width, height))
 {
      using (var dc = DrawingContext.FromBitmap(bmp))
      {
          //繪圖操作
      }
 }

 

Bitmap的指標和畫素操作

        /// <summary>
        /// 將圖片轉換成黑白色效果
        /// </summary>
        /// <param name="bmp">原圖</param>
        public static unsafe void GrayScale(Bitmap bmp)
        {
            //確定影象的寬和高
            int height = bmp.Height;
            int width = bmp.Width;

            using (var l = bmp.Lock())
            {//l.DataPointer就是資料指標,一般不建議直接使用,因為不同平臺,不同圖形介面卡,不同點陣圖格式,資料格式不一樣,那你就需要判斷不同格式來遍歷指標資料處理了
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        l.GetPixel(x, y, out byte a, out byte r, out byte g, out byte b);
                        var p = (byte)Math.Min(255, 0.7 * r + (0.2 * g) + (0.1 * b));
                        l.SetPixel(x, y, a, p, p, p);
                    } // x
                } // y
            }
        }