question

Stevo-9229 avatar image
0 Votes"
Stevo-9229 asked MatthewEno-7805 edited

SkiaSharp SKImageFilter.CreateDistantLitDiffuse clipped

I'm trying to reproduce lightning effect similar to this one https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/effects/image-filters#lighting-effects, but my content is a SKPath as opposed to Text

What I'd like to achieve is for the effect to only change colour of my Path (stroke with specific width), as opposed to everything around it (background)

I've tried clipping the canvas with my Path, but that does not work because I need the path to have Stroke with specific Width, and that cannot be reproduced by transforming a path.

As you can see on the attached picture, the SKImageFilter.CreateDistantLitDiffuse effect it applied to full canvas, and I'd only like to apply it to the SKPath object

Any ideas?

94537-capture.png


dotnet-xamarin
capture.png (25.9 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Stevo-9229 avatar image
0 Votes"
Stevo-9229 answered Stevo-9229 edited

After more research, I've found Porter Duff blend modes, and was essentially able to clip the canvas to only the part that I cared about with simple BledMode:

 using (var paint = new SKPaint())
 {
     paint.BlendMode = SKBlendMode.DstIn;
     canvas.DrawImage([instance of SKImage containing the content I wanted to use as clip], new SKPoint(), paint);
 }

More info at https://skia.org/docs/user/api/skblendmode_overview/

@JessieZhang-2116



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JessieZhang-2116 avatar image
0 Votes"
JessieZhang-2116 answered MatthewEno-7805 edited

Hello,


Welcome to our Microsoft Q&A platform!


What I'd like to achieve is for the effect to only change colour of my Path (stroke with specific width)

As a workaround, I think you can use the SKImageFilter.CreateDropShadow to achieve this.

Take the official sample SkiaSharpForms/Demos for example, Specially,pay attention to page DropShadowExperimentPage.xaml.cs,

The code is

     void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
     {
         SKImageInfo info = args.Info;
         SKSurface surface = args.Surface;
         SKCanvas canvas = surface.Canvas;

         canvas.Clear();

         // Get values from sliders
         float dx = (float)dxSlider.Value;
         float dy = (float)dySlider.Value;
         float sigmaX = (float)sigmaXSlider.Value;
         float sigmaY = (float)sigmaYSlider.Value;

         using (SKPaint paint = new SKPaint())
         {
             // Set SKPaint properties
             paint.TextSize = info.Width / 7;
             paint.Color = SKColors.Blue;
             paint.ImageFilter = SKImageFilter.CreateDropShadow(
                                     dx,
                                     dy,
                                     sigmaX,
                                     sigmaY,
                                     SKColors.Red,
                                     SKDropShadowImageFilterShadowMode.DrawShadowAndForeground); 

             SKRect textBounds = new SKRect();
             paint.MeasureText(TEXT, ref textBounds);

             // Center the text in the display rectangle
             float xText = info.Width / 2 - textBounds.MidX;
             float yText = info.Height / 2 - textBounds.MidY;

             canvas.DrawText(TEXT, xText, yText, paint);
         }
     }

When we change the Horizontal offset or Vertical offset, we can call followig code for the SKCanvasView:

   canvasView.InvalidateSurface();

The result is:
94618-image.png


Best Regards,


Jessie Zhang


If the response is helpful, please click "Accept Answer" and upvote it.



Note: Please follow the steps in our [documentation][6] to enable e-mail notifications if you want to receive the related email notification for this thread.



image.png (10.3 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @JessieZhang-2116

thanks for responding.

Whilst DropShadow appears similar, (albeit more complicated to achieve the same visual appearance), it performs really terribly with the same content.

So in this case DropShadow workaround does not work I'm afraid.

Any smart way of removing the lighning effect from the background?

0 Votes 0 ·

Hi @JessieZhang-2116 ,

I'm having a similar problem when using canvas.DrawText with SKImageFilter.CreateDistantLitDiffuse, where it is filling the background with the light colour, even if it set it to transparent.

SKImageFilter.CreateDistantLitDiffuse gives me exactly the embossed effect that I want, but I need it to have a transparent background, so as to still display the background image I've applied to the canvas. The Drop Shadow isn't good enough for what I'm after. Is there a work-around for this?

0 Votes 0 ·