1

I've tried a lot of different solutions in the last two days, but can't seem to find the best way.

What I want is:

1. Show image
2. Enable drawing red lines on image
3. Save image with lines

I've tried Win2D, WriteableBitmapEx, InkCanvas, normal Canvas and the Lumia Imaging SDK, but haven't had luck with at working solution. There is big chance that I'm doing it all wrong, since all those solutions don't work for me. I can't seem to find any good examples that work with UWP though. Anyone know a nice and easy way to do this?

EDIT: I'm developing in C#

stonecompass
  • 547
  • 9
  • 27
  • Can you show one of the solutions you tried that doesn't work so someone can tell you where the problem is? That's better than asking for complete solutions. – Igor Ralic Oct 29 '15 at 10:59

1 Answers1

6

1) The first solution is using DX. You can render to the screen using Direct2D and DirectWrite and then save the rendered image to disk using the WIC API. If you are writing a Windows Store app, you can have the user select a destination file using Windows::Storage::Pickers::FileSavePicker. Here you can find a sample program.

For more complete samples about using DX in UWP to render or save images, you can refer here.

2) If you want to use pure c#, win2D is good wrapper for direct2D, which can used to draw image. With the help of RenderTargetBitmap, you can render an arbitrary UIElement into a bitmap. As about RenderTargetBitmap, here is MSDN paper, and here is good sample.

For your case, the code may look like below (You can save to file later):

XAML:

<StackPanel>
    <Button Content="Save as image source" Click="SaveImageSource_Click" />
    <Grid x:Name="RenderedGrid" Height="500"  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <canvas:CanvasControl Draw="CanvasControl_Draw" ClearColor="CornflowerBlue"/>
    <Image x:Name="RenderedImage" Stretch="None" />
    </Grid>
</StackPanel>

C#:

private  void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
    args.DrawingSession.DrawEllipse(155, 155, 80, 30, Colors.Black, 3);
    args.DrawingSession.DrawLine(155, 155, 180, 180, Colors.Red);
}

private async void SaveImageSource_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(RenderedGrid, 500, 500);
    RenderedImage.Source = renderTargetBitmap;
}

Please let me know if anything unclear.

Romasz
  • 29,662
  • 13
  • 79
  • 154
Fangfang Wu - MSFT
  • 1,062
  • 6
  • 7
  • Just realized that I forgot to mention it had to be in C#, since I'm not using C++. :-( – stonecompass Oct 29 '15 at 14:41
  • If using C#, win2D is good choice. Use the InkCanvas in UWP to draw lines, then save it as a BitmapImage afterwards from the StrokeContainer, like this: InkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream). You can find a total win2D samples here: https://github.com/Microsoft/Win2D/tree/master/samples – Fangfang Wu - MSFT Oct 30 '15 at 07:30
  • Okay, I will try your solution, but how would I merge the image that is drawn on with the lines afterwards? Because what I really what to do is draw a marking on an existing image, if that makes sense. – stonecompass Oct 30 '15 at 08:26
  • 1
    For pure c# solution, see the update in my first reply – Fangfang Wu - MSFT Oct 30 '15 at 09:40
  • 1
    Fantastic! Thank you so much! – stonecompass Oct 30 '15 at 10:16
  • 1
    Do you have anyway to convert that image to byte array? – gayan1991 Apr 27 '16 at 03:22