0

I was working on some image editing using System.Drawing, and now ported everything to SkiaSharp in order to use it on Linux / .NET Core. Everything works fine, except I have not yet found a way to programmatically give images rounded corners.

I wrote some code that relies on drawing a path in the form of a circle and then tries to color the outside of the path transparent. This does not work though since it seems like there are multiple layers and making parts of the upper layer transparent does not make the whole region of the image (all layers) transparent. Here is my code:

public static SKBitmap MakeImageRound(SKBitmap image)
{
    SKBitmap finishedImage = new SKBitmap(image.Width, image.Height);

    using (SKCanvas canvas = new SKCanvas(finishedImage))
    {
       canvas.Clear(SKColors.Transparent);
       canvas.DrawBitmap(image, new SKPoint(0, 0));
       SKPath path = new SKPath();
       path.AddCircle(image.Width / 2, image.Height / 2, image.Width / 2 - 1f);
       path.FillType = SKPathFillType.InverseEvenOdd;
       path.Close();
       canvas.DrawPath(path, new SKPaint {Color = SKColors.Transparent, Style = SKPaintStyle.Fill });
       canvas.ResetMatrix();              
       return finishedImage;
    }
}

I am sorry if this is bad code, this is my first experience with image editing in C#, and therefore I also am an absolute beginner in SkiaSharp. I modified a System.Drawing code I got from here.

I also took a look at this Microsoft document. It shows clipping using paths, but I have not yet been able to get that to work either.

So in conclusion: I am searching for a way to make all layers of an image/the canvas transparent in certain regions.

Any help is greatly appreciated! :D

Jakob Tinhofer
  • 313
  • 3
  • 16

1 Answers1

4

I think you can do this by setting the SPaint.BlendMode = SKPaintBlendMode.Src. That means that when the canvas is drawing, it just must use the source color, and replace the existing colors.

https://learn.microsoft.com/dotnet/api/skiasharp.skpaint.blendmode

What you are actually doing with

canvas.DrawPath(path, new SKPaint { Color = SKColors.Transparent});

is picking up a brush, dipping it in the transparent paint, and then drawing. So you see nothing. The paint is clear.

But, what you even more want to do is clip before drawing:

https://learn.microsoft.com/dotnet/api/skiasharp.skcanvas.clippath

canvas.Clear(SKColors.Transparent);

// create the circle for the picture
var path = new SKPath();
path.AddCircle(image.Width / 2, image.Height / 2, image.Width / 2 - 1f);

// tell the canvas not to draw outside the circle
canvas.ClipPath(path);

// draw the bitmap
canvas.DrawBitmap(image, new SKPoint(0, 0));
Matthew
  • 4,832
  • 2
  • 29
  • 55