読者です 読者をやめる 読者になる 読者になる

プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

WPFのInkCanvasで塗りつぶす

f:id:puni-o:20161201111926j:plain

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で塗りつぶしています

結果

f:id:puni-o:20161201112430g:plain

塗りつぶせました

あとは閉じた領域だけ塗るようにすればいい感じになりそうなんですが、閉じた領域ってどうやって探すんだろう・・・