question

MisterXamarin-2605 avatar image
0 Votes"
MisterXamarin-2605 asked NicoleLu-9366 commented

Xamarin Forms : SkiaSharp Crop and Resize

I try to implement cropping image in my app but not a rectangle Cropping (like in the demo https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/bitmaps/cropping)
I would like to create a " polygonal" cropping from a photo (similar to camscanner).

So the first step is ok : with SkiaSharp I get a canvas from my EdgeCroppingView like this

82058-image.png


So now I want catch the selection and "resize" in full screen only the selection (around the cat) but i have this result :

82006-crop2.png

It seems only the SkPath was resizing correctly but not the "inside selection" .


Here's my canvas after cropping :

canvas.ClipPath(_pathToClip); -> this is content area i would like to resize...


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

     canvas.Clear();

     if (_pathToClip != null)
     {
          SKRect rectSource;
         _pathToClip.GetTightBounds(out rectSource);

         e.Surface.Canvas.Clear();
         SKRect canvasRect = SKRect.Create(e.Info.Size);

         //I need to find the size of the path
         SKRect pathRect = _pathToClip.TightBounds;

         //I want to find the largest rectangle that can fit on my canvas maintaining the path's aspect ratio
         //SkiaSharp added a builtin method for this based on code from me

         SKRect drawPathRect = canvasRect.AspectFit(pathRect.Size);
         //Now I need to transform the path to draw within the drawPathRect
         //First translate original path to its own origin
         SKMatrix firstTranslateM = SKMatrix.CreateTranslation(-pathRect.Left, -pathRect.Top);
         //Next handle scaling.  Since I maintained aspect ratio, I should be able to use either
         //width or height to figure out scaling factor
         float scalingFactor = drawPathRect.Width / pathRect.Width;
         SKMatrix scaleM = SKMatrix.CreateScale(scalingFactor, scalingFactor);
         //Last I need to handle translation so path is centered on canvas
         SKMatrix secondTranslateM = SKMatrix.CreateTranslation(drawPathRect.Left, drawPathRect.Top);
         //Now combine the translation, scaling, and translation into a single matrix by matrix multiplication/concatentation
         SKMatrix transformM = SKMatrix.CreateIdentity();
         SKMatrix.PostConcat(ref transformM, firstTranslateM);
         SKMatrix.PostConcat(ref transformM, scaleM);
         SKMatrix.PostConcat(ref transformM, secondTranslateM);
            
         //Now apply the transform to the path
         _pathToClip.Transform(transformM);
            

         canvas.ClipPath(_pathToClip);

        using (var paint = new SKPaint())
         {
             paint.Style = SKPaintStyle.Stroke;
             paint.Color = SKColors.Magenta;
             paint.StrokeWidth = 5;

             canvas.DrawPath(_pathToClip, paint);
             canvas.DrawBitmap(Bitmap, info.Rect, BitmapStretch.UniformToFill );
         }

          
     }


dotnet-xamarin
image.png (363.6 KiB)
crop2.png (366.8 KiB)
· 1
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.

@MisterXamarin-2605 I think you'll need to do some math to calculate your new image's height and width and determin the minimal scale against the canvas's width and height, then scale the picture. Could you provide some simple demo so that I can try that based on your implementation?

0 Votes 0 ·

0 Answers