DrawTool画笔之纹理笔

先上图:

12

今天我们要实现的是DrawTool画笔集合中的一种纹理笔,很多人可能对纹理笔概念还比较生疏,其实如果你接触过类似一些教育行业交互式白板的话,对纹理笔并不会感到陌生,纹理笔我们可以简单的理解为是一种通过图片来呈现笔迹的方式.在继续下面的阅读前,你有必要先了解下以下知识:

通过上面的文章,我们知道DynamicRenderer为我们提供是呈现,而Stroke是最后我们生成笔迹,如果要实现纹理笔,我们需要重载DynamicRenderer的OnDraw和Stroke的DrawCore方法.

1. 自定义Stroke

public  class TextureStroke : Stroke
    {
        private System.Windows.Media.ImageSource imageSource_;
        //纹理图片
        private string textureFile_;
        public TextureStroke(StylusPointCollection stylusPoints, DrawingAttributes da , string file )
            : base(stylusPoints, da)
        {
            this.textureFile_ = file;
            this.imageSource_ = new System.Windows.Media.Imaging.BitmapImage(new Uri(this.textureFile_));
        }

        /// <summary>
        /// 实现绘制
        /// </summary>
        /// <param name="drawingContext"></param>
        /// <param name="drawingAttributes"></param>
        protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes)
        {
            double width = drawingAttributes.Width * 2.0;
            System.Windows.Media.StreamGeometry streamGeometry = new System.Windows.Media.StreamGeometry();
            using (System.Windows.Media.StreamGeometryContext streamGeometryContext = streamGeometry.Open())
            {
                streamGeometryContext.BeginFigure((Point)base.StylusPoints[0], false, false);
                foreach (System.Windows.Input.StylusPoint current in base.StylusPoints)
                {
                    streamGeometryContext.LineTo((Point)current, true, true);
                }
                streamGeometryContext.Close();
            }

            DrawTexture(streamGeometry, this.imageSource_, drawingContext, width, this.textureFile_);
        }

        public static void DrawTexture(Geometry geometry, ImageSource imageSource, DrawingContext drawingContext, double width, string imagePath)
        {
            Rect rc = geometry.Bounds;
            DrawingBrush drawingBrush = new DrawingBrush(new ImageDrawing
            {
                Rect = rc,
                ImageSource = imageSource
            });
            drawingBrush.TileMode = TileMode.Tile;
            Uri uriSource = new Uri(imagePath);
            BitmapImage bitmapImage = new BitmapImage(uriSource);
            drawingBrush.Viewport = new Rect(0.0, 0.0, (double)bitmapImage.PixelWidth, (double)bitmapImage.PixelHeight);
            drawingBrush.ViewportUnits = BrushMappingMode.Absolute;
            PathGeometry widenedPathGeometry = geometry.GetWidenedPathGeometry(new Pen(null, width)
            {
                StartLineCap = PenLineCap.Round,
                EndLineCap = PenLineCap.Round
            });
            Pen pen = new Pen(drawingBrush, 80.0);
            drawingContext.PushClip(widenedPathGeometry);
            drawingContext.DrawRectangle(drawingBrush, pen, rc);
            drawingContext.Pop();
        }
    }

2.实例应用

这里我们使用到上篇文章中介绍的多点触摸画板 ,修改其中_startStroke方法中stroke对象的生成,相应代码如下:

bool isTexturePen = true ; // 外部定义的私有变量

private void _startStroke(object device, Point inputPosition){
  // ... { some code }

 
 //==这里根据变量isTexturePen来判断使用默认的stroke还是自定义的stroke
 Stroke stroke = isTexturePen==true ? new TextureStroke( stylusPointCollection , this._inkCanvas.DefaultDrawingAttributes,"c:\1.png") :  new Stroke(stylusPointCollection);
//end

// .... { some code }
}

3. 结束

  DrawTool系列文章中涉及的代码都是通过修改后的,仅仅适用于demo场景,如果需要商业请自行修改,包括性能上的调整.

原文地址:https://www.cnblogs.com/andy1987/p/4349629.html