locked
Why is the image encoder producing blank images? RRS feed

  • Question

  • I am trying to use RenderTargetBitmap to capture a portion of my Visual Tree and save it in memory. After I ran into some problems with this I tried saving to a file instead and I'm ending up with an empty file. 

    enderTargetBitmap boardImage = new RenderTargetBitmap();
    await boardImage.RenderAsync(VisualRoot);
    var pixels = await boardImage.GetPixelsAsync();
    
    //pixels size  = 16257024
    //boardImage.Width = 2688
    //boardImage.Height = 1512
    
    rawBytes = pixels.ToArray();
    
    StorageFolder folder = KnownFolders.PicturesLibrary;
    StorageFile file = await folder.CreateFileAsync("sample.bmp", CreationCollisionOption.ReplaceExisting);
    
    
    using (FileRandomAccessStream fileStream = (FileRandomAccessStream)await file.OpenAsync(FileAccessMode.ReadWrite))
    {
    //fileStream.Position = 0
    //fileStream.Size = 0
        var fileEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
        fileEncoder.SetPixelData(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Ignore,
            (uint)boardImage.PixelWidth,
            (uint)boardImage.PixelHeight,
            96,
            96,
            (await boardImage.GetPixelsAsync()).ToArray()
        );
    
    //fileStream.Position = 0
    //fileStream.Size = 0
    
        await encoder.FlushAsync();
    await fileStream.FlushAsync(); //fileStream.Position = 0 //fileStream.Size = 0 }

    Upon exiting the program and checking my file system the file is there. But as suggested by the never changing fileStream.Size and fileStream.Position, the file is 0 bytes in length and has no content. I've tried using other combinations of alpha, pixel format, and encoder IDs but am getting fairly consistent results. 

    If I try the same thing with an InMemoryRandomAccessStream the Size updates, the Position stays at zero, and the contents are all 0 values.  Any idea what I am doing wrong?


    Joel Ivory Johnson | http://www.j2i.net | Windows Phone Developer MVP
    It takes all the running you can do to stay in one place.If you want to get somewhere else,you must try to run at least twice as fast as that.

    Monday, December 16, 2013 2:00 AM

Answers

  • Your code works correctly for me once the variables are all defined properly and consistently. I ended up with a bmp file matching my visual tree.

    In what context are you calling this? That could be the difference. In my test I called it when an element was tapped.

    --Rob

    • Marked as answer by Anne Jing Thursday, December 26, 2013 2:09 AM
    Tuesday, December 17, 2013 7:41 AM
    Moderator
  • It was a simple mistake. I had a second stream object that I accidentally reference when actually writing the data. It seems that when I was retyping the code here I unknowingly correct the mistake. So it doesn't show here. 

    Thanks for taking a look at it!


    Joel Ivory Johnson | http://www.j2i.net | Windows Phone Developer MVP
    It takes all the running you can do to stay in one place.If you want to get somewhere else,you must try to run at least twice as fast as that.


    Tuesday, December 17, 2013 3:27 PM

All replies

  • That looks superficially correct. I'll take a closer look when I'm at a dev machine in a few hours. You extract the pixels twice and casting to FileRandomAccessStream isn't necessary, but that shouldn't cause subtle problems here.

    To diagnose I'd start by figuring out where the problem is. Does the RenderTargetBitmap get good data? Can you see it correctly in an Image control? If not, then make sure  it targets appropriate elements, etc. If so, then examine the file encoding code more closely.

    --Rob

    Monday, December 16, 2013 3:55 PM
    Moderator
  • Your code works correctly for me once the variables are all defined properly and consistently. I ended up with a bmp file matching my visual tree.

    In what context are you calling this? That could be the difference. In my test I called it when an element was tapped.

    --Rob

    • Marked as answer by Anne Jing Thursday, December 26, 2013 2:09 AM
    Tuesday, December 17, 2013 7:41 AM
    Moderator
  • It was a simple mistake. I had a second stream object that I accidentally reference when actually writing the data. It seems that when I was retyping the code here I unknowingly correct the mistake. So it doesn't show here. 

    Thanks for taking a look at it!


    Joel Ivory Johnson | http://www.j2i.net | Windows Phone Developer MVP
    It takes all the running you can do to stay in one place.If you want to get somewhere else,you must try to run at least twice as fast as that.


    Tuesday, December 17, 2013 3:27 PM