SkiaSharp 不使用 StrokeAndFill 填充三角形

Posted

技术标签:

【中文标题】SkiaSharp 不使用 StrokeAndFill 填充三角形【英文标题】:SkiaSharp does not fill triangle with StrokeAndFill 【发布时间】:2017-07-25 19:02:49 【问题描述】:

我正在尝试绘制和填充一个三角形。我提到了一个 android - 问题How to draw filled triangle on android Canvas 并做了以下事情。它绘制了三角形,但没有填充它。如何填满?另外,是否可以用与线条颜色不同的颜色填充它?

Xamarin 表单

private void OnPainting(object sender, SKPaintSurfaceEventArgs e)

        var surface = e.Surface;
        var canvas = surface.Canvas;
        canvas.Clear(SKColors.White);


        var pathStroke2 = new SKPaint
        
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(244, 0, 110, 200),
            StrokeWidth = 5
        ;

        var path2 = new SKPath  FillType = SKPathFillType.EvenOdd ;
        path2.MoveTo(0, 0);
        path2.LineTo(0, 140);
        path2.MoveTo(0, 140);
        path2.LineTo(140, 140);
        path2.MoveTo(140, 140);
        path2.LineTo(0, 0);
        path2.Close();
        canvas.DrawPath(path2, pathStroke2);

    

【问题讨论】:

尝试删除额外的 MoveTo 调用 - 这可能会混淆填充算法? @Jason 谢谢。删除 MoveTo 就成功了。您可以将其发布为答案吗?另外,你能告诉我是否有任何 GitHub 项目可以参考高级 SkiaSharp 示例? 【参考方案1】:

您不需要同时使用 LineTo() 和 MoveTo() - 我怀疑这样做会破坏填充算法。相反,只需使用

path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.LineTo(140, 140);
path2.LineTo(0, 0);
path2.Close();

【讨论】:

MoveTo 打破填充的原因是因为移动开始了一条新路径。 SKPath 可以包含多个路径。在您的示例中,您只是关闭最后一条路径的最后一段。【参考方案2】:

根据 Jason 的评论,删除不需要的 MoveTo 行解决了这个问题。

以下是完整的代码。

   private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
   

        var surface = e.Surface;
        var canvas = surface.Canvas;
        canvas.Clear(SKColors.White);

        var w = e.Info.Width;
        var h = e.Info.Height;

        SKColor[] colors;
        colors = new SKColor[] 
                 new SKColor(244, 0, 110, 200), new SKColor(244, 0, 110, 220),
                 new SKColor(244, 0, 110, 240),new SKColor(244, 0, 110, 240),
                 new SKColor(244, 0, 100,240),
                 new SKColor(244, 0, 100),
                 new SKColor(255, 0, 70)
                ;
        SKShader shaderLeft = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(w, h), colors, null, SKShaderTileMode.Clamp);
        var paint = new SKPaint()  Shader = shaderLeft ;
        canvas.DrawPaint(paint);


       var path2 = new SKPath  FillType = SKPathFillType.EvenOdd ;
        path2.MoveTo(0, 0);
        path2.LineTo(0, 140);
        path2.LineTo(140, 140);
        path2.LineTo(0, 0);
        path2.Close();

        var pathStroke2 = new SKPaint
        
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(0, 0, 0, 30),
            StrokeWidth = 5
        ;

        using (var cf = SKColorFilter.CreateBlendMode(new SKColor(244, 0, 110, 200), SKBlendMode.DstIn))
        
            var transparency = SKColors.White.WithAlpha(127); 
            pathStroke2.ColorFilter = cf;

            // ... draw ...
            canvas.DrawPath(path2, pathStroke2);

            pathStroke2.ColorFilter = null;
        

        var pathStroke3 = new SKPaint
        
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(0, 0, 0, 30),
            StrokeWidth = 5
        ;

        var path3 = new SKPath  FillType = SKPathFillType.EvenOdd ;
        path3.MoveTo(170, 0);
        path3.LineTo(170, 140);
        path3.LineTo(300, 140);
        path3.LineTo(170, 0);
        path3.Close();
        canvas.DrawPath(path3, pathStroke3);

    

【讨论】:

以上是关于SkiaSharp 不使用 StrokeAndFill 填充三角形的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在 SkiaSharp 中“叠加”不透明度

SkiaSharp ConicTo 方法不绘制曲线

如何使用 SkiaSharp 测量尾随空格?

在 Visual Studio 中使用 SkiaSharp

如何使用 SkiaSharp 查找解码位图的 PixelFormat

SkiaSharp 和 GPU 加速