CPF 入门教程 - 绘图(四)

CPF NetCore跨平台UI框架,增加了Vlc支持跨平台播放视频。

 

系列教程

CPF 入门教程(一)

CPF 入门教程 - 数据绑定和命令绑定(二)

CPF 入门教程 - 样式和动画(三)

CPF 入门教程 - 绘图(四)

 

一般来说是不需要自己写绘图代码的,大部分UI效果通过控件元素(CPF.Shapes提供基础图形控件)组合和SVG组合就可以实现。

如果需要自定义控件绘制特殊的控件,可以继承Control或者UIElement重写OnRender方法来绘制自己需要的效果。调用 Invalidate 或者在依赖属性上设置AffectsRender来刷新界面。

        /// 
        /// 背景填充
        /// 
        [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);
                  }
             }
        }

其中BackgroundViewFill 类型,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的指针和像素操作

        /// 
        /// 将图片转换成黑白色效果
        /// 
        /// 原图
        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
            }
        }

 

 

你可能感兴趣的:(CPF 入门教程 - 绘图(四))