Code Sample: Windows 8 Input: Ink sample in C#/Xaml
In the previous part of this series, we talked about how to use efficiently the inking namespace in WinRT. As you may recall the main component in this drawing adventure was InkManager. In this part of the series, we will be talking about how we can save the strokes to an image file and later on load and render these stokes.
Saving the Ink Stokes
In WinRT API, the only function that InkManager exponses for saving strokes is the SaveAsync method. This might be quite disappointing for most since in good old silverlight, one could easily load an InkPresenter to WriteableBitmap and manupulate it as he/she wants.
try { Windows.Storage.Pickers.FileSavePicker save = new Windows.Storage.Pickers.FileSavePicker(); save.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop; save.DefaultFileExtension = “.png”; save.FileTypeChoices.Add(“PNG”, new string[] { “.png” }); StorageFile filesave = await save.PickSaveFileAsync(); using (IOutputStream fileStream = await filesave.OpenAsync(FileAccessMode.ReadWrite)) { if (fileStream != null) { await m_InkManager.SaveAsync(fileStream); } } } catch (Exception ex) { var dialog = new MessageDialog(ex.Message); dialog.ShowAsync(); }
In this implementation we are using a FileSavePicker to create a file, but we could as well use an InMemoryRandomAccessStream. Using the memory stream also help you to display the image in an Image control right away. (e.g. You might want to preview the image that is drawn in a smaller size.)
Loading the Ink Strokes
When the ink strokes are serialized into an image file, you as well load these strokes back to an InkManager and also use them to render the image for further editing perhaps..
using (IRandomAccessStream stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read)) { await m_InkManager.LoadAsync(stream); if (m_InkManager.GetStrokes().Count > 0) { // RenderStrokes(); } }
You could possibly use the same render function that was outlined on the previous article.
Further Implementation
The saving of the ink strokes creates a rectangle that is only a small cutout from the whole canvas. (e.g. Canvas.ActualWidth = InkManager.BoundingRectangle.Left + InkManager.BoundingRectangle.Width + InkManager.BoundingRectangle.Right) Still trying to figure out how to include the whole canvas area in the image that is saved.
The main reason for this cropped version of the canvas is the fact that even though we are saving the stokes to a “PNG” file (and the microsoft version uses “GIF”), the file is actually in ISF format (*.isf). You can as well rename the extension to .isf and open the image file with paint and save it as “*.png”. You will notice that the magic number change on the file binary and the file size change.
UPDATE: Next post in the series about updating the solution and using the Select/Copy/Paste features.
Good luck everyone, happy coding.
Pingback: Drawing / Inking API in WinRT (C#) – I | Can Bilgin
Pingback: Windows 8 Developer Links – 2012-08-13Dan Rigby | Dan Rigby
Thanks this is helpful to me
LikeLike
how can we save the strokes with the background of the canvas ?
LikeLike
Did you find a way to make the ink strokes Rectangle the same size as the canvas to mantain the position when loading the image again? Thanks in advance!
LikeLike
Can i get irandomaccessstream without saving file?
LikeLike
Pingback: Drawing / Inking API in WinRT (C#) – III | Can Bilgin