Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BitmapEncoder FlushAsync() never returns

I've scoured the web for this and not found a solution yet. I have a DispatchTimer in my Universal phone app. On each tick, I want to capture a portion of the screen and save it to JPEG. My code seems very straightforward, and there are no crashes -- it simply never returns from the FlushAsync(). It seems like it must be a deadlock scenario, but I haven't been able to find where the conflict is yet:

using (var ms = new MemoryStream())
{
    var renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(ctrl);
    var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();

    using (var ras = ms.AsRandomAccessStream())
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras, propertySet);

        encoder.SetPixelData(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Premultiplied,
            (uint) renderTargetBitmap.PixelWidth,
            (uint) renderTargetBitmap.PixelHeight,
            logicalDpi, logicalDpi,
            pixelBuffer.ToArray());

        await encoder.FlushAsync();
    }

    return ms.ToArray();
}

Any help would be great! I've been at this for hours, trying different ways to get it working with no luck.

like image 762
Arian Kulp Avatar asked Nov 24 '15 22:11

Arian Kulp


1 Answers

I figured it out! Turns out you can't just use MemoryStream.AsRandomAccessStream() as your encoder destination. Turns out you should just use the InMemoryRandomAccessStream, then afterwards get the bytes:

byte[] bytes = new byte[ras.Size];
await ras.AsStream().ReadAsync(bytes, 0, bytes.Length);
return bytes;

Not sure why MemoryStream caused the problem it did, but this is a pretty easy fix! I hope this helps someone else.

like image 147
Arian Kulp Avatar answered Oct 21 '22 06:10

Arian Kulp