切换PC时,InkCanvas Strokes不会以适当的边界呈现

时间:2017-04-07 14:38:40

标签: uwp inkcanvas

我有一个UWP应用程序使用带有加载和保存墨水按钮的UWP InkCanvas。我在一台笔记本电脑上用应用程序绘制了一个平局,将墨水保存为gif(+ embedded isf)并将gif文件发送到另一台带有较小屏幕的笔记本电脑上试用。

当使用相同的应用程序打开墨水但是在另一台笔记本电脑上时,绘图会在边界处被剪裁,好像它不适合屏幕,这可能是由于笔记本电脑的屏幕尺寸较小。

我试图通过将InkCanvas封装在Scrollviewer中来整体调整InkCanvas的大小,但是绘图遵循InkC​​anvas缩放,因此绘制仍然在边界处被剪裁。与InkCanvas上的渲染变换相同。我还在加载墨水时尝试了StrokeContainer的复制粘贴方法。它不起作用,而且我发现它很笨重,因为需要循环遍历所有笔划以选择它们然后复制粘贴。

我正在研究一种自动调整InkCanvas(首选)或Strokes的方法,使绘图完全出现在InkCanvas上,无论笔记本电脑屏幕的大小如何。我希望这可以在默认情况下发生,但有些情况并非如此。

虽然我使用的代码非常简单,但我将其作为开头提供:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid Background="White" Grid.Row="1">
         <InkCanvas x:Name="inkCanvas"/>
    </Grid> 
    <StackPanel>
            <Button Content="Load" Click="LoadButton_Click"/>
            <Button Content="Save" Click="SaveButton_Click"/>
    </StackPanel>
</Grid>


    private async void LoadButton_Click(object sender, RoutedEventArgs e)
    {
        FileOpenPicker openPicker = new FileOpenPicker();
        openPicker.FileTypeFilter.Clear();
        openPicker.FileTypeFilter.Add(".isf");
        openPicker.FileTypeFilter.Add(".gif");

        openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;

        StorageFile file = await openPicker.PickSingleFileAsync();

        if (file != null)
        {
            IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);

            using (var inputStream = stream.GetInputStreamAt(0))
            {
                await inkCanvas.InkPresenter.StrokeContainer.LoadAsync(inputStream);
            }
            stream.Dispose();

     }
    }

1 个答案:

答案 0 :(得分:3)

The StrokeContainer.SaveAsync() method will create a GIF. I am not sure exactly how it preserves the ink stroke data, but it seems to be point for point. Since your InkCanvas is stretching based on its parent Grid, its final bounds will be different screen to screen, and even in resized UWP window.

So, when you reload the stroke data, it will put the points exactly where it was generated. It will not transform anything for you. This is raw data.

If you want the data to appear in a different location, you can apply a transformation on the points. Here's a quick sample of how to shrink all data by 50%:

var container = inkCanvas.InkPresenter.StrokeContainer;
var strokes = container.GetStrokes();
var bounds = container.BoundingRect;
var center = new Vector2((float)bounds.Left, (float)bounds.Top);
var transform = Matrix3x2.CreateScale(.5f, .5f, center);

foreach (var stroke in strokes)
{
    stroke.PointTransform *= transform;
}

You could put that snippet of code after await container.LoadAsync(inputStream).

You need to decide what to do with your output. It will depend on the user experience you want. If you want to scale the output, use the snippet above. If you want to move it, then use Matrix3x2.CreateTranslation(...).