0

I have a function in my code behind that does what I want. What I like about this is no matter how the user expand his drawing out of the InkCanvas boundries, the image will be resized when saved.

private void exportCanvasToBitmap(object sender, EventArgs e) {

RenderTargetBitmap rtb = new 
RenderTargetBitmap((int)signatureCanvas.ActualWidth, 
(int)signatureCanvas.ActualHeight, 96, 96, PixelFormats.Default);
        rtb.Render(signatureCanvas);

        BmpBitmapEncoder encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(rtb));
        FileStream fs = File.Open(@".\images\"+ signatureFileName + ".jpg", FileMode.Create);
        encoder.Save(fs);
        fs.Close();
        (sourceWindow as MainWindow).updateSignatureImage(signatureType, signatureFileName);
    }

I wanted to move this to the ViewModel and I didn't know how to make it does the same as the one I have before. I don't want to usertb.Render(inkCanvas) in the ViewModel. After some search I binded a StrokeCollection to my view and used this function.

  public void convertStrokestoImage() {

        StrokeCollection sc = strokes;

        byte[] inkData = null;

        using (MemoryStream inkMemStream = new MemoryStream())

        {

            sc.Save(inkMemStream);

            inkData = inkMemStream.ToArray();

        }

        byte[] gifData = null;


        using (Microsoft.Ink.Ink ink2 = new Microsoft.Ink.Ink())
          {

            ink2.Load(inkData);

            gifData = ink2.Save(Microsoft.Ink.PersistenceFormat.Gif); 

        }

        File.WriteAllBytes("./Src/strokes.png", gifData);

    }

The problem with this is that if the user draws out of the InkCanvas' boundaries, the image scales " which I don't want". I am not really sure how to do that since both of the function I found online as solutions in other questions.

My initial thought is that I have to do something similar for what I had before where I had a RenderTargetBitmap that has the actual width and height of my InkCanvas. The issue is I don't know how to obtain this without using InkCanvas object itself.

any tips?

Muhannad
  • 467
  • 4
  • 28
  • Anything in [there](https://stackoverflow.com/questions/855334/wpf-how-to-make-canvas-auto-resize) helps you? – Kilazur Mar 12 '18 at 11:48
  • No. MVVM != no codebehind. Keep your UI code in your codebehind, and pass the result to the view model via an ICommand binding. Cramming UI logic into view models is the biggest misconception new devs have about the pattern. Keep your business logic out of your UI and your UI out of your business logic. –  Mar 12 '18 at 19:58
  • @Kilazur hello I am looking on resizing the image not the Inkcanvas itself. – Muhannad Mar 13 '18 at 01:32
  • @Will hello I understand your point, however I'm trying to force MVVM in my current code for the sake of learning it. – Muhannad Mar 13 '18 at 01:34
  • The first thing you need to learn, then, is not to cram UI code into your view model :) –  Mar 13 '18 at 13:21
  • @Will drawing the strokes is a UI logic; however, converting the image and saving it I think it's a business logic. – Muhannad Mar 13 '18 at 14:17
  • Considering how easy it is to convert WPF controls to bitmaps, you'll have a much easier time of it in the UI. –  Mar 13 '18 at 14:32

1 Answers1

0

I solved the issue like this.

First I converted the byte[] to an Image and then I used a helper function to resize the image.

 public void convertStrokestoImage()
    {

        StrokeCollection sc = strokes;

        byte[] inkData = null;

        using (MemoryStream inkMemStream = new MemoryStream())

        {

            sc.Save(inkMemStream);

            inkData = inkMemStream.ToArray();

        }

        byte[] gifData = null;


        using (Microsoft.Ink.Ink ink2 = new Microsoft.Ink.Ink())
        {

            ink2.Load(inkData);

            gifData = ink2.Save(Microsoft.Ink.PersistenceFormat.Gif);

        }

        MemoryStream ms = new MemoryStream(gifData);
        Image image = Image.FromStream(ms);
        image = resizeImage(image, 100, 150);
        image.Save("./Src/strokes.png");

    }

You can find alot of functions to resize images in the following question. Resize an Image C#

What I don't like about this is the image file size become bigger! For example what was 5kb became 30kb.

Muhannad
  • 467
  • 4
  • 28