How do I emboss text with a transparent background using SkiaSharp?

375 Views Asked by At

I'm using SkiaSharp to draw text onto a canvas that I've already drawn a background image onto.

It's working fine when just drawing regular text, but I want to add an embossed effect to the text. To do this, I've tried using SKImageFilter.CreateDistantLitDiffuse, which gives the right effect, but the problem is that it fills the background with the light color (also influenced by the diffuse lighting constant). This ends up obliterating my background.

The image below shows the text with the embossed effect, but as you can see, it's background is not transparent. Also, the text should be white, but it's colour has been changed by the filter.

enter image description here

The image filter I'm using is:

fontPaint.ImageFilter = SKImageFilter.CreateDistantLitDiffuse(
                                    new SKPoint3(2, 3, 4),
                                    SKColors.Transparent,
                                    -3,
                                    (float)0.2)

canvas.DrawText(element.Value, coords, fontPaint);

I've seen examples of embossing by drawing the text twice with an offset, but this doesn't give the desired effect.

Any ideas of how I can work-around this issue with the image filter filling in the background?

1

There are 1 best solutions below

0
Matt Eno On

I managed to get pretty close to what I'm wanting by using CreateMatrixConvolution.

 float[] kernel = new float[25]
                {
                    -1,  0, -.5f,  0,  0,
                     0, -1, -.5f,  0,  0,
                    -.5f, -.5f,  1.5f,  .5f,  .5f,
                     0,  0,  .5f,  1,  0,
                     0,  0,  .5f,  0 , 1
                };

                
 fontPaint.ImageFilter = SKImageFilter.CreateMatrixConvolution(
               new SKSizeI(5,5), kernel, 1f, 1f, new SKPointI(1, 1), 
               SKMatrixConvolutionTileMode.Clamp, true);

This gives me the following result:

enter image description here

It's not exactly the same as what I was wanting, which is more like this:

enter image description here

But it's pretty close. If anyone has any suggestions on how I can get it closer to the example above, I'd love to hear it. Possibly tweaking the kernel might work, but I've already spent ages playing around with variations.