Question

I'm creating and application that needs to add and remove a lot of UIElement to a Canvas. Basically a Canvas contains a collection of UIElement and automatically renders/updates it on the screen depending what it contains.

In order to avoid having a tons of UIElements who overlap each others on the screen I prefer to add all of them on a secondary Canvas then create a Image from it (thanks to WritableBitmap). Finally I add this Image on my current Canvas. By allowing to have only few image on my Canvas I expect to have better performance. Unfortunately it seems I can't delete completely the WritableBitmap, even if I set it to null.

The following code illustrates it :

//My constructor
public  WP8Graphics() 
{
    //Here my collection DataBinded with the Canvas from the Mainpage
    this.UIElements = new ObservableCollection<UIElement>();
    //The secondary Canvas
    GraphicCanvas = new Canvas();
    GraphicCanvas.Height = MainPage.CurrentCanvasHeight;
    GraphicCanvas.Width = MainPage.CurrentCanvasWidth;
}


///This method can be hit thousand times, it basically create a rectangle 
public void fillRect(int x, int y, int width, int height)
{

// some code
// CREATE THE RECTANGLE rect

   GraphicCanvas.Children.Add(rect); // My secondary Canvas



   WriteableBitmap wb1 = new WriteableBitmap(GraphicCanvas, null);
   wb1.Invalidate();

   WriteableBitmap wb2 = new WriteableBitmap((int)MainPage.CurrentCanvasWidth, (int)MainPage.CurrentCanvasHeight);

  for (int i = 0; i < wb2.Pixels.Length; i++)
  {
       wb2.Pixels[i] = wb1.Pixels[i];
  }
  wb2.Invalidate();

  wb1 = null;

  Image thumbnail = new Image();
  thumbnail.Height = MainPage.CurrentCanvasHeight;
  thumbnail.Width = MainPage.CurrentCanvasWidth;
  thumbnail.Source = wb2;



  this.UIElements.Add(thumbnail);

}

After something like 24 WriteableBitmap created a OutOfMemoryException appears. I read many articles about this problem and in my case it seems the WriteableBitmap depends on my GraphicCanvas and remains because there still have a reference to it. I can't delete my Graphic Canvas nor set myImage source to null.

I have 2 question :

  • Is there another way to create an image from Canvas or a collection of UIElements ?
  • Is it possible to remove the reference who keeps that WriteableBitmap alive ?

I hope to be enough clear and easy to read.

Thank you for reading.

EDITED with atomaras suggestion, but still the same problem

WriteableBitmap wb1 = new WriteableBitmap(GraphicCanvas, null); This line still throws OutOfMemoryException.

Was it helpful?

Solution

You need to copy the pixels of the original writeablebitmap (that will hold on to the GraphicsCanvas) to a new writeablebitmap.

Take a look at this great post http://www.wintellect.com/blogs/jprosise/silverlight-s-big-image-problem-and-what-you-can-do-about-it

Also why do you keep all of the writeablebitmaps in the UIElements collection? Wouldn't the latest one suffice? Cant you clear the UIElements collection right before adding the latest/new bitmap?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top