2

I am just looking around and tried to making a working version of saving multiple canvas as one image. For example would be nice to save them nearby each other, but I can not figure out how to do it.

public static void CreateSaveBitmap(Canvas canvas1, Canvas canvas2, string filename)
    {
        RenderTargetBitmap renderBitmap1 = new RenderTargetBitmap((int)canvas1.ActualWidth, (int)canvas1.ActualWidth, 96d, 96d, PixelFormats.Pbgra32);
        // needed otherwise the image output is black
        canvas1.Measure(new Size((int)canvas1.ActualWidth, (int)canvas1.ActualWidth));
        canvas1.Arrange(new Rect(new Size((int)canvas1.ActualWidth, (int)canvas1.ActualWidth)));

        renderBitmap1.Render(canvas1);

        RenderTargetBitmap renderBitmap2 = new RenderTargetBitmap((int)canvas2.ActualWidth, (int)canvas2.ActualWidth, 96d, 96d, PixelFormats.Pbgra32);
        // needed otherwise the image output is black
        canvas2.Measure(new Size((int)canvas2.ActualWidth, (int)canvas2.ActualWidth));
        canvas2.Arrange(new Rect(new Size((int)canvas2.ActualWidth, (int)canvas2.ActualWidth)));

        renderBitmap2.Render(canvas2);

        //JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        PngBitmapEncoder encoder = new PngBitmapEncoder();

        encoder.Frames.Add(BitmapFrame.Create(renderBitmap1));
        encoder.Frames.Add(BitmapFrame.Create(renderBitmap2));
        using (FileStream file = File.Create(filename))
        {
            encoder.Save(file);
        }
    }

This is how I tried, but its only saving the first image. Can someone help me to solve this please?

UPDATE

I corrected some mistakes what told by @TheLethalCoder, and I also changed the output filetype to Tiff, but it doesn't helped. This is the latest version now:

public static void CreateSaveBitmap(Canvas canvas1, Canvas canvas2, string filename)
    {
        RenderTargetBitmap renderBitmap1 = new RenderTargetBitmap((int)canvas1.ActualWidth, (int)canvas1.ActualHeight, 96d, 96d, PixelFormats.Pbgra32);
        // needed otherwise the image output is black
        canvas1.Measure(new Size((int)canvas1.ActualWidth, (int)canvas1.ActualHeight));
        canvas1.Arrange(new Rect(new Size((int)canvas1.ActualWidth, (int)canvas1.ActualHeight)));

        renderBitmap1.Render(canvas1);

        RenderTargetBitmap renderBitmap2 = new RenderTargetBitmap((int)canvas2.ActualWidth, (int)canvas2.ActualHeight, 96d, 96d, PixelFormats.Pbgra32);
        // needed otherwise the image output is black
        canvas2.Measure(new Size((int)canvas2.ActualWidth, (int)canvas2.ActualHeight));
        canvas2.Arrange(new Rect(new Size((int)canvas2.ActualWidth, (int)canvas2.ActualHeight)));

        renderBitmap2.Render(canvas2);

        //JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        TiffBitmapEncoder encoder = new TiffBitmapEncoder();

        encoder.Frames.Add(BitmapFrame.Create(renderBitmap1));
        encoder.Frames.Add(BitmapFrame.Create(renderBitmap2));
        using (FileStream file = File.Create(filename))
        {
            encoder.Save(file);
        }
    }
3
  • What type of image are you trying to save it as? And you're setting all your heights as widths Commented Oct 13, 2015 at 14:02
  • Oh png just saw it, try saving as a tiff or something that supports multiple frames... Commented Oct 13, 2015 at 14:04
  • I fixed what you said thank you, but it doesnt helped Commented Oct 13, 2015 at 14:43

1 Answer 1

1

What you want is not multiple-frame image but to combine the images of your canvases by juxtaposing them. So actually you need just 1 Frame here but a big combined one. There are some ways to combine them but there is 1 simple way you can do with DrawingVisual. We can draw a Drawing on that visual and use RenderTargetBitmap to capture it. We use DrawingGroup to combine the ImageDrawings (from the 2 RenderTargetBitmaps). In summary, we have to do the following steps: from 2 RenderTargetBitmaps, you put them in 2 ImageDrawings and combine those into a DrawingGroup. Then you draw that combined Drawing on a DrawingVisual. Finally use RenderTargetBitmap to render that visual normally.

Here is the code you can try out:

public static void CreateSaveBitmap(Canvas canvas1, Canvas canvas2, string filename)
{
    RenderTargetBitmap renderBitmap1 = new RenderTargetBitmap((int)canvas1.ActualWidth, (int)canvas1.ActualHeight, 96d, 96d, PixelFormats.Pbgra32);

    canvas1.Measure(new Size((int)canvas1.ActualWidth, (int)canvas1.ActualHeight));
    canvas1.Arrange(new Rect(new Size((int)canvas1.ActualWidth, (int)canvas1.ActualHeight)));

    renderBitmap1.Render(canvas1);

    RenderTargetBitmap renderBitmap2 = new RenderTargetBitmap((int)canvas2.ActualWidth, (int)canvas2.ActualHeight, 96d, 96d, PixelFormats.Pbgra32);

    canvas2.Measure(new Size((int)canvas2.ActualWidth, (int)canvas2.ActualHeight));
    canvas2.Arrange(new Rect(new Size((int)canvas2.ActualWidth, (int)canvas2.ActualHeight)));

    renderBitmap2.Render(canvas2);

    //Combine the images here
    var dg = new DrawingGroup();
    var id1 = new ImageDrawing(renderBitmap1, 
                               new Rect(0,0,renderBitmap1.Width, renderBitmap1.Height));
    var id2 = new ImageDrawing(renderBitmap2,
                               new Rect(renderBitmap1.Width, 0
                                        renderBitmap2.Width,
                                        renderBitmap2.Height));
    dg.Children.Add(id1);
    dg.Children.Add(id2);
    var combinedImg = new RenderTargetBitmap((int)(renderBitmap1.Width + renderBitmap2.Width + 0.5),
                          (int)(Math.Max(renderBitmap1.Height, renderBitmap2.Height) + 0.5), 96, 96, PixelFormats.Pbgra32); 
    var dv = new DrawingVisual();
    using(var dc = dv.RenderOpen()){
       dc.DrawDrawing(dg);
    }
    combinedImg.Render(dv);

    //JpegBitmapEncoder encoder = new JpegBitmapEncoder();
    PngBitmapEncoder encoder = new PngBitmapEncoder();

    encoder.Frames.Add(BitmapFrame.Create(combinedImg));

    using (FileStream file = File.Create(filename)) {
        encoder.Save(file);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.