Skip to content

Need help DrawInk(inkStrokes) and StrokeContainer.BoundRect resizing issue #505

@Ponant

Description

@Ponant

Hi,
I would really appreciate some guidance or solution as I am struggling on a seemingly simple issue about saving a set of strokes from a UWP InkCanvas to a PNG file, with the condition that I want the PNG image to fit the strokes boundaries and not the whole InkCanvas. For some reason, rendering to PNG works well for some collection of strokes, but at other times it cuts the image at the boundaries, either left or right, or top or bottom and I am unable to find a solution. I provide here the necessary code to make it run as well as a sample ink file which reproduces the issue. The red rectangle in the code is here to show the BoundRect of the StrokeContainer.
Here is one Gif with embedded ISF:  ink file .

You load it and save as PNG and check out the borders. Thanks a lot if you can help me.

XAML

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid x:Name="topGrid" Grid.Row="1">
            <Grid x:Name="inkCanvasGrid" BorderBrush="Yellow" BorderThickness="2"
                  Background="White">
                <InkCanvas x:Name="inkCanvas"/>
                <Rectangle x:Name="rectangle" Fill="Red" Opacity="0.5" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top"/>
            </Grid>
        </Grid>

        <StackPanel>
            <Button Content="Load" Click="LoadButton_Click"/>
            <Button Content="Save" Click="SaveButton_Click"/>
        </StackPanel>
    </Grid>

C#

private async void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Any())
            {
                var fileSave = new FileSavePicker();

                fileSave.FileTypeChoices.Add("PNG", new string[] { ".png" });

                fileSave.SuggestedStartLocation = PickerLocationId.PicturesLibrary;

                var storageFile = await fileSave.PickSaveFileAsync();

                if (storageFile != null)
                {
                    //dataText.Text = $"selected {storageFile.FileType}";
                    using (var stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        await SaveInkToStream(stream, storageFile.FileType);
                    }
                }
            }
        }

        private async Task SaveInkToStream(IRandomAccessStream stream, string fileType)
        {
            //var strokeContainerWidth = inkCanvas.ActualWidth;
            //var strokeContainerHeight = inkCanvas.ActualHeight;

            var strokeContainerBoundRect = inkCanvas.InkPresenter.StrokeContainer.BoundingRect;

            rectangle.RenderTransform = new TranslateTransform
            {
                X = strokeContainerBoundRect.X,
                Y = strokeContainerBoundRect.Y,

            };
            rectangle.Height = strokeContainerBoundRect.Height;
            rectangle.Width = strokeContainerBoundRect.Width;

            CanvasDevice device = CanvasDevice.GetSharedDevice();

            using (var renderTarget = new CanvasRenderTarget(device, (float)strokeContainerBoundRect.Width, (float)strokeContainerBoundRect.Height, 96f))
            {

                using (CanvasDrawingSession ds = renderTarget.CreateDrawingSession())
                {
                    ds.Transform = new Matrix3x2() { M11 = 1, M22 = 1, Translation = new Vector2((float)-strokeContainerBoundRect.X, (float)-strokeContainerBoundRect.Y)};
                    ds.Clear(Colors.White);
                    ds.DrawInk(inkCanvas.InkPresenter.StrokeContainer.GetStrokes());
                }

                await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png, 1f);
            }
        }

        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);

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

            }
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions