Manual Image Crop Layer on Xamarin.Forms [Part 1]

Enrique Ramos Vargas
3 min readJul 2, 2020

--

Implementing a 4 sided polygon cropping layer on Xamarin.Forms. Go to second part of this post if you don’t need this visual layer. 🥤🥤

The problem

I need to allow user to crop himself or herself a 4 sided polygon shape of an image. Basically a sheet of paper or something like that.

The only control I found was the Syncfusion Image Editor control, which is great although it doesn’t fit to my needs at all. I only need four draggable corner points that allow users select a 4 sided polygon. That’s all. Then I would use OpenCv to both cropping the image with the corner coordinates and fixing the perspective.

The solution

My solution is a custom control composed by a HoleLayerView and 4 draggable BoxViews with rounded corners on top of it.

HoleLayerView is responsible of drawing the transparent 4 sided polygon hole and black line borders.

I called the view I place over the Cuphead image ManualCropView. This XF custom controls has 5 children: a HolaLayerView and 4 draggable trasnparent Frames containing BoxViews with rounded corners.

First of all I wait for layout width and height because my cropping control need to know the screen limits. That way balls are unable to get off screen.

Then I simply needed to add a PanGestureRecognizer to each corner ball and update their TranslationX and TranslationY while PanGesture running.

Be careful with PanGestureRecognizer because it works differently in Android and iOS, which is really weird and annoying IMHO, but this is out of this post scope.

On each TranslationX and TranslationY for each corner you must sync the corner ball position with the hole polygon redrawing it.

HoleLayerView

This control has Point porperties and a method DrawRectangle that draws the 4 sided polygon hole. The (only) interesting part of this post are the native renderers.

Android renderer is a ViewRenderer that overrides OnDraw method, where you can draw over the view’s canvas.

This method will be called each time the view should be rendered. So each time you need OnDraw is called (when a corner ball is translated) you have to invalidate the view render.

iOS renderer is a UIView renderer with two CAShapeLayer as sublayers. I draw the transparent 4 sided polygon hole in the first sublayer and the black line borders in the second one each time a corner ball is translated.

Golly! The post is finished! 🥤🥤

All code in this working example in my Github.

--

--