Hi!
I am trying to implement SkiaSharp in order to be able to draw on an image, which works great, also with the ability in picking different colours.
But when I change the orientation, the drawn lines move out of position until I change back the orientation to the orientation in which the drawing is made (see attachments).
I think understand why this is happening, but I can't figure out how to fix this.
I tried setting the canvas.Scale() and also transforming the paths with SKMatrix.MakeScale() but I didn't get the correct results.
I am still experimenting, but this is the piece of code I am working on at the moment.
SKImageInfo info = args.Info; SKSurface surface = args.Surface; canvas = surface.Canvas; canvas.Clear(); float scale = Math.Min((float)info.Width / resourceBitmap.Width, (float)info.Height / resourceBitmap.Height); float x = (info.Width - scale * resourceBitmap.Width) / 2; float y = (info.Height - scale * resourceBitmap.Height) / 2; destRect = new SKRect(x, y, x + scale * resourceBitmap.Width, y + scale * resourceBitmap.Height); canvas.ClipRect(destRect); using (new SKAutoCanvasRestore(canvas)) { BitmapExtensions.DrawBitmap(canvas, resourceBitmap, destRect, BitmapStretch.AspectFit, BitmapAlignment.Center, BitmapAlignment.Center); } foreach (FingerPaintPolyline polyline in completedPolylines) { paint.Color = polyline.StrokeColor.ToSKColor(); paint.StrokeWidth = polyline.StrokeWidth; canvas.DrawPath(polyline.Path, paint); } foreach (FingerPaintPolyline polyline in inProgressPolylines.Values) { paint.Color = polyline.StrokeColor.ToSKColor(); paint.StrokeWidth = polyline.StrokeWidth; canvas.DrawPath(polyline.Path, paint); }
I am hoping to get some tips / advise.
Thanks in advance.
Best Regards,
Bas
Answers
Your BitmapExtensions.DrawBitmap is drawing the image to fit the canvas which causes its dimensions and location to change regarding raw pixel x,y coordinates. I am also guessing you are storing your drawing annotations in raw pixel x,y coordinates which are NOT changing when you rotate. Therefore, the do not align when you rotate since image changed but drawing annotations did not change.
One way to do this is to NOT store the drawing annotations points in raw pixel x,y coordinates, but instead as percentages of the underlying image. So a dot drawn in the upper left corner of the image would be stored as 0%,0% and a dot drawn in the lower right corner of the image would be stored as 100%,100%. Then before you draw the annotations on top of the image, you have to convert the percentages back to raw pixel x,y values based on the NEW image location. So for example, a dot stored as 50%,75% would be converted to raw pixel x,y (assuming destRect is the exact Rect the image fills up, which it may not be, not sure):
I am not suggesting that this is the best way to do it nor the only way to do it, but it is one way to do it.
Here is some sample code. I show in comments how to manually convert each point on the path from a percentage point to a canvas point. However, I did NOT take care to maintain the separate segments of the SKPath so the conversion links them altogether. Therefore, I switch to use a SKMatrix and then calling Transform on the SKPath which DOES maintain the separate segments. I have also attached the screenshots of portrait and landscape to show the annotation stays on top of the image in the correct location.
@Basserd
Have you got the solution ? If yes ,could you please share it with us?