locked
RenderTargetBitmap.GetPixelsAsync() returns nullptr even after calling RenderAsync()

    Question

  • I need to save a canvas element to an image file, but I cannot get the pixels from the RenderTargetBitmap object. 

    My code looks like this

    RenderTargetBitmap^ renderTargetBitmap = ref new RenderTargetBitmap();

    create_task(renderTargetBitmap->RenderAsync(canvas)).then( [this, renderTargetBitmap, stream]() { create_task(renderTargetBitmap->GetPixelsAsync()).then( [this, stream](IBuffer^ pixels) { SaveImage(pixels, stream); }); });


    The problem is that pixels is a null. Why is this happening?

    Thank you,

    David



    • Edited by davidb353 Monday, February 17, 2014 11:09 PM
    Monday, February 17, 2014 11:08 PM

Answers

  • Interesting. I can repro now. The same code in C# works fine without adding to an image. I'll dig into this further and let you know what I find.

    --Rob

    • Marked as answer by davidb353 Thursday, February 20, 2014 5:55 PM
    Thursday, February 20, 2014 4:06 PM
    Moderator

All replies

  • Hi David,

    Could you please share a sample project for this?

    -Sagar

    Tuesday, February 18, 2014 11:06 AM
    Moderator
  • Your code looks at least superficially correct. Can you explain more about the actual symptoms and where and how this is called (as Sagar suggests, a minimal repro sample would help clarify things).

    Is your canvas in the visual tree and visible when this is called?

    Take a look at the RenderTargetBitmap Remarks and make sure you aren't calling this in an unsupported scenario.

    --Rob

    Tuesday, February 18, 2014 5:23 PM
    Moderator
  • This code is being called in the event handler for a bottom app bar button. The canvas is visible and inside of a scroll viewer. I will send a sample soon.


    • Edited by davidb353 Tuesday, February 18, 2014 6:49 PM
    Tuesday, February 18, 2014 6:48 PM
  • Ok, I created a minimal sample with the same problem. It can be found here

    https://skydrive.live.com/redir?resid=D34F3CE0E38E7E12!40670&authkey=!AKY0YPGnzVMG8HI&ithint=file%2c.zip


    • Edited by davidb353 Tuesday, February 18, 2014 7:48 PM
    Tuesday, February 18, 2014 7:07 PM
  • The code looks good and the sample's Xaml looks fine. I'm not able to reproduce the problem with the sample code: GetPixelsAsync delivers an IBuffer to the pixels variable as expected.

    Source snippet with a pointer in the pixels

    Tuesday, February 18, 2014 9:21 PM
    Moderator
  • pixels is definitely null for me. Do I need a windows or visual studio update?

    Tuesday, February 18, 2014 9:47 PM
  • Adding an Image control to the xaml and then adding the line

    img->Source = renderTargetBitmap

    at line 55 makes the problem go away. Very strange to me. Can you please explain this? 

    Why do I have to make the renderTargetBitmap the source of an Image control to get the pixel data?



    • Edited by davidb353 Tuesday, February 18, 2014 10:27 PM
    Tuesday, February 18, 2014 10:15 PM
  • Ensure you have the latest updates for Visual Studio and please post the versions you have installed (from the about box) after ensuring you have the latest updates and the problem persists.

    Jeff Sanders (MSFT)

    @jsandersrocks - Windows Store Developer Solutions @WSDevSol
    Getting Started With Windows Azure Mobile Services development? Click here
    Getting Started With Windows Phone or Store app development? Click here
    My Team Blog: Windows Store & Phone Developer Solutions
    My Blog: Http Client Protocol Issues (and other fun stuff I support)

    Thursday, February 20, 2014 3:04 PM
    Moderator
  • Interesting. I can repro now. The same code in C# works fine without adding to an image. I'll dig into this further and let you know what I find.

    --Rob

    • Marked as answer by davidb353 Thursday, February 20, 2014 5:55 PM
    Thursday, February 20, 2014 4:06 PM
    Moderator
  • I have VS Professional 2013 , version 12.0.30110.00 Update 1. I had this problem before and after I installed the update.

    Thursday, February 20, 2014 5:59 PM
  • I was facing the same issue and fixed it by passing renderTargetBitmap as parameter to the then call. It seems renderTargetBitmap's pixels are disposed before the image can be saved.

    RenderTargetBitmap^ renderTargetBitmap = ref new RenderTargetBitmap();
    
    
    create_task(renderTargetBitmap->RenderAsync(canvas)).then([this, renderTargetBitmap, stream]()
    {
    	create_task(renderTargetBitmap->GetPixelsAsync()).then([this, stream, renderTargetBitmap](IBuffer^ pixels) 
    	{
    		//renderTargetBitmap is not being used here, but should be referenced above, else pixels will be null
    		SaveImage(pixels, stream);
    	});
    });
    
    

    • Proposed as answer by Pascal Kuyten Tuesday, September 23, 2014 4:10 AM
    Tuesday, September 23, 2014 4:10 AM