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:
.
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();
}
}
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
InkCanvasto a PNG file, with the condition that I want the PNG image to fit the strokes boundaries and not the wholeInkCanvas. 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:
You load it and save as PNG and check out the borders. Thanks a lot if you can help me.
XAML
C#