locked
Draw annotation by using skiasharp is not working properly RRS feed

  • Question

  • User312663 posted

    Hello, My issue is that I am using skiasharp to draw annotation inside a listview.when i am drawing then it is shown to all the rows of the listview but i want it to the selected rows or item.Can anyone help me to how can I draw only on that particular row.Can anyone suggest me another dll to implement this or I am using the correct one for this?

    Tuesday, May 23, 2017 12:56 PM

Answers

  • User68536 posted

    I had a look, and I managed to get this working by just adding the code from other SkiaSharp samples:

    • https://developer.xamarin.com/guides/xamarin-forms/advanced/skiasharp/paths/finger-paint
    • https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/effects/touch-tracking

    The attached sample has custom list items, each of which can be drawn on separately.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, May 26, 2017 2:22 AM
  • User68536 posted

    If you want to save the paths, right now the best way would be to first convert the paths to a serializable format (eg: string) and then save that. SKPath has a ToSvgPathData method:

    SKPath path = ...;
    string serialized = path.ToSvgPathData();
    SKPath deserialized = SKPath.ParseSvgPathData(serialized);
    

    Here is some example to seriealize the paths into a list of strings that can be saved somewhere:

    var serialized = listItem.CompletedPaths.Select(p => p.ToSvgPathData());
    

    Hope this helps!

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Monday, May 29, 2017 4:46 PM

All replies

  • User68536 posted

    I have a sample that you could check out. It is a data-bound list, and each item is painted differently based on the item.

    Let me know if it helps.

    note: duplicate of https://forums.xamarin.com/discussion/96128/skiasharp-drawing-issue-inside-listview

    Tuesday, May 23, 2017 3:24 PM
  • User312663 posted

    @Matthew Leibowitz I think you are not getting my point.I am using skiasharp with the for finger paint.I am using touch effect class to draw over the list item.when I am drawing a line then it will appear to all the rows of that list.I am not able to find out the position of the list item so that I can draw only on that item.Are you getting my point?

    Wednesday, May 24, 2017 4:40 AM
  • User68536 posted

    I had a look, and I managed to get this working by just adding the code from other SkiaSharp samples:

    • https://developer.xamarin.com/guides/xamarin-forms/advanced/skiasharp/paths/finger-paint
    • https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/effects/touch-tracking

    The attached sample has custom list items, each of which can be drawn on separately.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, May 26, 2017 2:22 AM
  • User312663 posted

    Thank u soooo... much Matthew.This is what I want.One more thing sir.....I have searched to erase the finger paint but I didn't find it anywhere.Can you please share any link related to this.In the finger paint demo also it is not there.And Can we save this artwork?

    Friday, May 26, 2017 8:41 AM
  • User68536 posted

    No problem,

    To erase the line, you could have some way of drawing a line, but then when the line is finished - instead of adding it to the list, just remove the ones that intersect with the existing lines.

    Also, to save the art, you can just create a new surface and draw the lines to that:

    var surface = SKSurface.Create(new SKImageInfo(100, 100)); foreach (var path in paths) { surface.Canvas.DrawPath(path, ...); } SKImage image = surface.Snapshot(); SKData data = image.Encode(...);

    Friday, May 26, 2017 4:26 PM
  • User312663 posted

    Hey Mathhew,Thanks for the solution..... I have an issue that I have to save that artwork not as a image.I have to save that list so that we can show that drawing again to the user and they can draw again.I have tried it with the sharedpreference but I cannot save that list.Is there any other way to save it?

    And to erase the art I have already tried this but not working.

     case TouchActionType.Released:
                        if (listItem.InProgressPaths.ContainsKey(args.Id))
                        {
                            foreach (SKPath skpath in listItem.CompletedPaths)
                            {
                                for (int i = 0; i < skpath.PointCount; i++)
                                {
                                    SKPoint skPoint = skpath.GetPoint(i);
                                    SKPoint skPoint2 = ConvertToPixel(canvasView, args.Location);
                                    if (skPoint == skPoint2)
                                    {
                                        listItem.CompletedPaths.Remove(listItem.InProgressPaths[args.Id]);
                                    }
                                }
                            }
                            listItem.InProgressPaths.Remove(args.Id);
                            canvasView.InvalidateSurface();
                        }
                        break;
    

    here I an checking SKPoint but I am not getting the exact point....

    Monday, May 29, 2017 11:31 AM
  • User68536 posted

    If you want to save the paths, right now the best way would be to first convert the paths to a serializable format (eg: string) and then save that. SKPath has a ToSvgPathData method:

    SKPath path = ...;
    string serialized = path.ToSvgPathData();
    SKPath deserialized = SKPath.ParseSvgPathData(serialized);
    

    Here is some example to seriealize the paths into a list of strings that can be saved somewhere:

    var serialized = listItem.CompletedPaths.Select(p => p.ToSvgPathData());
    

    Hope this helps!

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Monday, May 29, 2017 4:46 PM
  • User312663 posted

    Can you plz help me on the earse path.because I am trying to do this but its not working.Is there any other way to do this?

    case TouchActionType.Released: if (listItem.InProgressPaths.ContainsKey(args.Id)) { foreach (SKPath skpath in listItem.CompletedPaths) { for (int i = 0; i < skpath.PointCount; i++) { SKPoint skPoint = skpath.GetPoint(i); SKPoint skPoint2 = ConvertToPixel(canvasView, args.Location); if (skPoint == skPoint2) { listItem.CompletedPaths.Remove(listItem.InProgressPaths[args.Id]); } } } listItem.InProgressPaths.Remove(args.Id); canvasView.InvalidateSurface(); } break;

    Thursday, June 1, 2017 4:13 AM
  • User312663 posted

    One more thing Matthew....when I am trying to draw from up to down or down to up then it is not working properly.Do you have any solution for this?

    Thursday, June 1, 2017 10:31 AM
  • User312663 posted

    I cannot read image from the resources/drawable.I have to use that image in the SKcanvas view to drawbitmap.Please tell me how can I get that path or image?

    Thursday, June 1, 2017 1:04 PM
  • User314441 posted

    Hello, i have the same issue but i'm using a listview with Group Header. Well i'm unable to select the group header of the listview with that method: var listItem = (sender as SKCanvasView)?.BindingContext as Mymodel; It's always returning Null.

    Thanks in advance.

    Tuesday, October 3, 2017 11:52 AM
  • User380936 posted

    @PragatiSahu said: Hey Mathhew,Thanks for the solution..... I have an issue that I have to save that artwork not as a image.I have to save that list so that we can show that drawing again to the user and they can draw again.I have tried it with the sharedpreference but I cannot save that list.Is there any other way to save it?

    And to erase the art I have already tried this but not working.

     case TouchActionType.Released:
                        if (listItem.InProgressPaths.ContainsKey(args.Id))
                        {
                            foreach (SKPath skpath in listItem.CompletedPaths)
                            {
                                for (int i = 0; i < skpath.PointCount; i++)
                                {
                                    SKPoint skPoint = skpath.GetPoint(i);
                                    SKPoint skPoint2 = ConvertToPixel(canvasView, args.Location);
                                    if (skPoint == skPoint2)
                                    {
                                        listItem.CompletedPaths.Remove(listItem.InProgressPaths[args.Id]);
                                    }
                                }
                            }
                            listItem.InProgressPaths.Remove(args.Id);
                            canvasView.InvalidateSurface();
                        }
                        break;
    

    here I an checking SKPoint but I am not getting the exact point....

    hey , did you resolve this problem? if yes then please share you knowledge . thank you

    Thursday, July 16, 2020 10:24 AM