1

I have some method that converts System.Windows.Controls.Canvas Control to .png Image and save in a directory. I Call this functions for some List <Canvas> and I get all the images in some directory. It is working fine but some times this function generates some of the images blank randomly also again calling this function generates all images perfectly. what could be reason behind this malfunctioning? Below is the Function

  public bool GenerateICards(Canvas surface)
        {
            bool retVal = false;
            try
            {
                // Save current canvas transform
                Transform transform = surface.LayoutTransform;
                // reset current transform (in case it is scaled or rotated)
                surface.LayoutTransform = null;

                // Get the size of canvas
                Size size = new Size(surface.Width, surface.Height);

                // Measure and arrange the surface
                // VERY IMPORTANT
                surface.Measure(size);
                surface.Arrange(new Rect(size));

                // Create a render bitmap and push the surface to it
                RenderTargetBitmap renderBitmap =
                  new RenderTargetBitmap(
                    (int)size.Width,
                    (int)size.Height,
                    96d,
                    96d,
                    PixelFormats.Pbgra32);
                renderBitmap.Render(surface);

                // Create a file stream for saving image
                using (FileStream outStream = new FileStream(SessionHelper.Path.PrintImage, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    // Use png encoder for our data
                    PngBitmapEncoder encoder = new PngBitmapEncoder();
                    // push the rendered bitmap to it
                    encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
                    // save the data to the stream
                    encoder.Save(outStream);
                }
                // Restore previously saved layout
                surface.LayoutTransform = transform;
                // i++;
                retVal = true;
            }
            //}
            catch (Exception)
            {
                ErrorLbl = "Error occured while generating temporary images.";
            }
            return retVal;
        }
SST
  • 459
  • 3
  • 20
  • 35
  • 1
    You need to make sure it's done a Render pass....see this... http://stackoverflow.com/questions/1080375/force-rendering-of-a-wpf-control-in-memory and http://blogs.msdn.com/b/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx – Colin Smith Oct 29 '12 at 11:11
  • Thanks..2nd link that you provided helped me a lot. Got the solution from that post. – SST Oct 29 '12 at 11:45
  • Related and considering objects outside the visible area: https://stackoverflow.com/questions/67472818/how-to-get-visible-size-of-canvas – Thomas Weller May 10 '21 at 15:26

1 Answers1

1

Just replaced

renderBitmap.Render(surface);

line in the function(function in above mentioned question) with

 Rect bounds = VisualTreeHelper.GetDescendantBounds(surface);
                DrawingVisual dv = new DrawingVisual();
                using (DrawingContext ctx = dv.RenderOpen())
                {
                    VisualBrush vb = new VisualBrush(surface);
                    ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
                }

                renderBitmap.Render(dv);

and this solved my problem. For details check out: http://blogs.msdn.com/b/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx

This link is provided by colinsmith(In the question's comment part).

SST
  • 459
  • 3
  • 20
  • 35