Hi I need help of how to get the byte array from a SoftwareBitmap in C# UWP, so that I can send it via TCP socket.
I also have access to a "VideoFrame previewFrame" object which is where I get the SoftwareBitmap from.
I have seen online to do something like the following, however UWP does not support the wb.SaveJpeg(...). Unless I am missing something?
MemoryStream ms = new MemoryStream();
WriteableBitmap wb = new WriteableBitmap(myimage);
wb.SaveJpeg(ms, myimage.PixelWidth, myimage.PixelHeight, 0, 100);
byte [] imageBytes = ms.ToArray();
Any help, or pointers in the right direction, would be greatly appreciated.
Thanks, Andy
Sure, you can access an encoded byte[] array from a SoftwareBitmap.
See this example, extracting a jpeg-encoded byte[]:
// includes BitmapEncoder, which defines some static encoder IDs
using Windows.Graphics.Imaging;
private async void PlayWithData(SoftwareBitmap softwareBitmap)
{
    // get encoded jpeg bytes
    var data = await EncodedBytes(softwareBitmap, BitmapEncoder.JpegEncoderId);
    // todo: save the bytes to a DB, etc
}
private async Task<byte[]> EncodedBytes(SoftwareBitmap soft, Guid encoderId)
{
    byte[] array = null;
    // First: Use an encoder to copy from SoftwareBitmap to an in-mem stream (FlushAsync)
    // Next:  Use ReadAsync on the in-mem stream to get byte[] array
    using (var ms = new InMemoryRandomAccessStream())
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, ms);
        encoder.SetSoftwareBitmap(soft);
        try
        {
            await encoder.FlushAsync();
        }
        catch ( Exception ex ){ return new byte[0]; }
        array = new byte[ms.Size];
        await ms.ReadAsync(array.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
    }
    return array;
}
                        to get byte array from SoftwareBitmap you can use "SoftwareBitmap.CopyToBuffer"
But, first you need:
using System.Runtime.InteropServices.WindowsRuntime;
because of method AsBuffer() to byte[]
...
StorageFile file = await StorageFile.GetFileFromPathAsync(ImageFilePath);
using (IRandomAccessStream fileStream = await File.OpenAsync(FileAccessMode.Read),
                                           memStream = new InMemoryRandomAccessStream())
  {
  // Open a Stream and decode a JPG image
  BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
  var softwareBitmap = await decoder.GetSoftwareBitmapAsync();
  byte [] imageBytes = new byte[4*decoder.PixelWidth*decoder.PixelHeight];
  softwareBitmap.CopyToBuffer(imageBytes.AsBuffer());
  //...  now you can use the imageBytes[]
}
                        as far I know you cant do it. but you can work with SoftwareBitmap. see examples: https://msdn.microsoft.com/en-us/library/windows/apps/mt244351.aspx (SoftwareBitmap is private field of SoftwareBitmapSource.. .just read it via reflection... maybe this is totally wrong suggestion)
private async void SaveSoftwareBitmapToFile(SoftwareBitmap softwareBitmap, StorageFile outputFile)
{
    using (IRandomAccessStream stream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        // Create an encoder with the desired format
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        // Set the software bitmap
        encoder.SetSoftwareBitmap(softwareBitmap);
        // Set additional encoding parameters, if needed
        encoder.BitmapTransform.ScaledWidth = 320;
        encoder.BitmapTransform.ScaledHeight = 240;
        encoder.BitmapTransform.Rotation = Windows.Graphics.Imaging.BitmapRotation.Clockwise90Degrees;
        encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
        encoder.IsThumbnailGenerated = true;
        try
        {
            await encoder.FlushAsync();
        }
        catch (Exception err)
        {
            switch (err.HResult)
            {
                case unchecked((int)0x88982F81): //WINCODEC_ERR_UNSUPPORTEDOPERATION
                                                 // If the encoder does not support writing a thumbnail, then try again
                                                 // but disable thumbnail generation.
                    encoder.IsThumbnailGenerated = false;
                    break;
                default:
                    throw;
            }
        }
        if (encoder.IsThumbnailGenerated == false)
        {
            await encoder.FlushAsync();
        }
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With