c#InkStrokeBuilder丢失数据

时间:2016-10-26 11:48:47

标签: c# canvas uwp

我有一个绘图项目,用户可以在其中创建绘图,将其备份到服务器并在其他地方使用(在其他平台上)

为实现这一目标,我只能使用以下对象备份Collection of Points方案中的绘图。

public class Drawing
{
    public Drawing()
    {
        points = new List<List<int>>();
    }
    public List<List<int>> points { get; set; }
    public string colour { get; set; }
}

我使用c#Inkmanager帮我绘制草图。为了保存,我提取笔划并将它们保存为点列表,如下所示。

private List<Drawing> GetDrawingsFromInkManager()
    {
        List<Drawing> returnList = new List<Drawing>();
        var strokes = m_InkManager.GetStrokes();

        int scount = 1;

        foreach (var s in strokes)
        {
            var renderingStrokes = s.GetRenderingSegments();

            Drawing drawing = new Drawing() { colour = m_CurrentDrawingColor.ToString() };

            foreach (var rs in renderingStrokes)
            {
                drawing.points.Add(new List<int>() { (int)rs.Position.X, (int)rs.Position.Y });
            }

            Debug.WriteLine("Drawing: " + scount++ + " points added: " + drawing.points.Count + " RenderSegmentsCount: " + renderingStrokes.Count);

            returnList.Add(drawing);

        }
        return returnList;
    }

结果输出为:

  

绘图:添加1分:33 RenderSegmentsCount:33

     

绘图:添加2点:22 RenderSegmentsCount:22

     

绘图:增加3分:21 RenderSegmentsCount:21

在此过程中,贝塞尔曲线数据丢失,现在不应该关注,因为一组直线段是可以接受的(点数仅相差1-2个像素)。

恢复点时,我使用c#StrokeBuilder类并传递一个点列表。但是,产生的笔划只有一半的笔画。

private void RestoreSegmentFromList(List<Point> pointList)
    {
        var color = m_CurrentMode == "Ink" ? m_CurrentDrawingColor : m_CurrentHighlightColor;
        var size = m_CurrentMode == "Ink" ? m_CurrentDrawingSize : m_CurrentHighlightSize;

        InkStrokeBuilder isBuiler = new InkStrokeBuilder();
        var points = pointList.Select(x => new Point(x.X* sketchScale, x.Y*sketchScale)).ToList();

        var inkStroke = isBuiler.CreateStroke(points);
        m_InkManager.AddStroke(inkStroke);

        Debug.WriteLine("Restoring; points added: " + points.Count + " RenderSegmentsCount: " + inkStroke.GetRenderingSegments().Count);

    }
  

恢复;积分:33 RenderSegmentsCount:16

     

恢复;积分:22 RenderSegmentsCount:14

     

恢复;积分:21 RenderSegmentsCount:12

我的问题,这是strokebuilder类的预期行为吗?我理解笔画的方式是它们由一个位置和两个贝塞尔控制点组成。该位置始终是笔划特定段的端点,前一段的终点是当前段的起点。但据我所知,上面的方法使用相同的方式来提取和创建。当然,如果我从inkManager获得X个渲染段,我应该能够仅使用一组点来恢复所述X数。我使用CreateStroke()方法错了吗?

1 个答案:

答案 0 :(得分:0)

  

要保存,我会提取笔划并将其保存为点列表。

为什么这样做,您可以使用InkStrokeContainer.SaveAsync | saveAsync method将所有while (managedCursor.moveToNext()) { String number = managedCursor.getString(number1); String type2 = managedCursor.getString(type1); String date = managedCursor.getString(managedCursor.getColumnIndexOrThrow("date")).toString(); java.util.Date date1 = new java.util.Date(Long.valueOf(date)); String duration = managedCursor.getString(duration1); String type = null; String fDate = date1.toString(); int callcode = Integer.parseInt(type2); sb.append("\nPhone Number:--- " + number + ""); sb.append(" \nCall Type:--- " + type + " "); sb.append("\nCall Date:--- " + fDate + ""); sb.append("\nCall duration in sec :--- " + duration); sb.append("\n----------------------------------"); } 个对象保存到指定的流中。有一个官方Simple inking sample,在方案3中,图纸可以保存到文件中并从文件中加载。如果您不想在本地保存,只需创建InkStroke,然后上传此流即可。例如:

InMemoryRandomAccessStream

如果您想在其他平台上加载此using (var stream = new InMemoryRandomAccessStream()) { await inkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream); //TODO: Upload this stream. } ,可以将其下载为流,然后:

InkStroke

这可能不是解决数据丢失问题的完美答案,但我认为这是Strokes正确保存和加载的方式,而且更加简单。