How to render InkCanvas to an image in UWP Windows 10 application?
Asked Answered
H

2

13

The RenderTargetBitmap class worked with simple Canvas + InkManager (in Windows 8.1) to render ink strokes to an image. UWP introduced InkCanvas and a new Inking API. However, it seems like the RenderTargetBitmap does not work with that. When I try to capture ink strokes with RenderAsync method, no ink strokes get rendered only other objects like Rectangle and so on.

Is it a bug or this new API is not meant to be used this way? If not, then how can I render an image out of InkCanvas?

Thanks!

Hymenopterous answered 22/8, 2015 at 8:7 Comment(5)
[inkCanvas].InkPresenter.StrokeContainer.SaveAsync can save as a .gifCheek
Yes, I'm aware of that. However, I guess it's an ISF (Ink Stroke Format) embedded in a .gif. The gif itself very ugly when opened, I can't use that. I definitely want to use RenderTargetBitmap, but it does not work as expected. I also tried decode the gif with BitmapDecoder, get the pixel data and encode it with BitmapEncoder to another format, also with no luck (it contains only zeros, the whole image is black). What I really want is to render a png or jpg image from it with white background for example. Maybe manipulate it later. Can anyone help?Hymenopterous
I tried to get back to the older InkManager + Canvas combination, but InkManager throws COM Exception when instantiated.Hymenopterous
OK, I'll have a solution which includes Win2D (Direct2D .NET wrapper from Microsoft). Win2D can be used in an UWP app via a nuget package. Very good stuff. I managed to save ink strokes to image (jpeg, png, and other formats) with this.Hymenopterous
@mudbox, I suggest you to write what you have found into an answer so it could help others.Nickolai
H
17

Here is how I solved this issue with Win2D. First of all, add Win2D.uwp nuget package to your project. Then use this code:

CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight, 96);

using (var ds = renderTarget.CreateDrawingSession())
{
    ds.Clear(Colors.White);
    ds.DrawInk(inkCanvas.InkPresenter.StrokeContainer.GetStrokes());
}

using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
    await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Jpeg, 1f);
Hymenopterous answered 13/9, 2015 at 16:1 Comment(6)
can you explain the code plz ? it's not clear. I want to draw on image picked from a file ..Ingrain
Everything you need to know is here. Please go through the content. microsoft.github.io/Win2D/html/Introduction.htm If you want to draw an image: 1. Make sure you added Win2D.uwp nugget package to your project (it only works with UWP as far as I know) 2. You'll need a CanvasControl in XAML <canvas:CanvasControl x:Name="canvas" ClearColor="White" CreateResources="CanvasControl_CreateResources" Draw="CanvasControl_Draw"/>Hymenopterous
3. Since loading a bitmap is async, you'll need this trickHymenopterous
Thanks ! Just to clarify I meant to draw strokes on an image and save it with the strokes as the same file .Ingrain
Then you need a control that holds the image in XAML (e.g.: Image, Canvas, etc.). You'll also need an InkCanvas (UWP) control on top of the image control. If you don't need to show the final rendered image in the UI, you can "offset draw". You just need to get the image source from the control that you want to draw as a background (I don't know this part, maybe you have to convert to bitmap), then load and call DrawImage on the drawing session. In the same session, you draw the ink strokes with DrawInk.Hymenopterous
To complete @mudbox's answer, you can load a bitmap like this CanvasBitmap backgroundBitmap = await CanvasBitmap.LoadAsync(device, filePath); and pass it into ds: ds.DrawImage(backgroundBitmap);Platelet
M
1

Please try InkPresenter.StrokeContainer property http://blogs.windows.com/buildingapps/2015/09/08/going-beyond-keyboard-mouse-and-touch-with-natural-input-10-by-10/

Mignon answered 11/9, 2015 at 9:1 Comment(1)
Welcome to Stack Overflow! Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.Rinaldo

© 2022 - 2024 — McMap. All rights reserved.