WPFのInkCanvasで塗りつぶす
InkCanvasは線を描くものっぽくて閉じた領域の塗りつぶし、みたいなことは標準ではできなさそうでした
ということでとりあえず適当に塗りつぶすようにしていみます
塗りつぶす人
System.Windows.Ink.Stroke
を継承してDrawCore
で塗りつぶすようにします
ソース
public class CustomInkCanvas : InkCanvas { protected override void OnStrokeCollected(InkCanvasStrokeCollectedEventArgs e) { this.Strokes.Remove(e.Stroke); var newStroke = new FillStroke(e.Stroke.StylusPoints, e.Stroke.DrawingAttributes); this.Strokes.Add(newStroke); base.OnStrokeCollected(new InkCanvasStrokeCollectedEventArgs(newStroke)); } } public class FillStroke : Stroke { public FillStroke(StylusPointCollection stylusPoints) : base(stylusPoints) { } public FillStroke(StylusPointCollection stylusPoints, DrawingAttributes drawingAttributes) : base(stylusPoints, drawingAttributes) { } protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes) { if (drawingContext == null) { throw new ArgumentNullException(nameof(drawingContext)); } if (null == drawingAttributes) { throw new ArgumentNullException(nameof(drawingAttributes)); } if (this.StylusPoints.Count < 3) return; var stroke = new Pen(Brushes.Blue, 2); stroke.Freeze(); var fill = new SolidColorBrush(Color.FromArgb(0x80, 0x00, 0xff, 0xff)); fill.Freeze(); var streamGeometry = new StreamGeometry(); using (var geometryContext = streamGeometry.Open()) { geometryContext.BeginFigure(this.StylusPoints[0].ToPoint(), true, false); var points = new PointCollection(); for (var i = 1; i < this.StylusPoints.Count; i++) { points.Add(this.StylusPoints[i].ToPoint()); } geometryContext.PolyLineTo(points, true, false); } drawingContext.DrawGeometry(fill, stroke, streamGeometry); } }
CustomInkCanvas
はStrokeが追加されたときにFillStroke
に置き換える処理をしています
FillStroke.DrawCore
で塗りつぶしています
結果
塗りつぶせました
あとは閉じた領域だけ塗るようにすればいい感じになりそうなんですが、閉じた領域ってどうやって探すんだろう・・・