locked
Windows 8 - How to convert BitmapImage into byte[]? RRS feed

  • Question

  • Hello everyone!

    How can I get a correct array of bytes from a BitmapSource object?

    Env: Microsoft Visual C# 11 Developer Preview

    Best Regards,

    Irina

    Friday, December 16, 2011 10:54 AM

Answers

  • Hi Anton,

    Thanks for your answer.

    I found the solution for my issue in this way:

     

            public static async Task<byte[]> GetPhotoBytesAsync(BitmapImage bitmapImage)

            {

                if (bitmapImage == null)

                    return new byte[0] { };

     

                WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);

                Stream stream = writeableBitmap.PixelBuffer.AsStream();

                byte[] pixels = new byte[stream.Length];

                await stream.ReadAsync(pixels, 0, pixels.Length);

     

                ConvertToRGBA(writeableBitmap.PixelHeight, writeableBitmap.PixelWidth, pixels);

     

                InMemoryRandomAccessStream ims = new InMemoryRandomAccessStream();

                var imsWriter = ims.OpenWrite();

                await Task.Factory.StartNew(() => stream.CopyTo(imsWriter));

                stream.Flush();

                stream.Dispose();

     

                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ims);

                encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, (uint)writeableBitmap.PixelWidth, (uint)writeableBitmap.PixelHeight, 96, 96, pixels);

                await encoder.FlushAsync();

     

                stream = ims.OpenRead();

                byte[] pixeBuffer = new byte[ims.Size];

                await stream.ReadAsync(pixeBuffer, 0, pixeBuffer.Length);

                stream.Flush();

                stream.Dispose();

     

                ims.GetOutputStreamAt(0).FlushAsync().Start();

               

                return pixeBuffer;

            }

     

            private static void ConvertToRGBA(int pixelHeight, int pixelWidth, byte[] pixels)

            {

                if (pixels == null)

                    return;

     

                int offset;

                for (int row = 0; row < (uint)pixelHeight; row++)

                {

                    for (int col = 0; col < (uint)pixelWidth; col++)

                    {

                        offset = (row * (int)pixelWidth * 4) + (col * 4);

                        byte B = pixels[offset];

                        byte G = pixels[offset + 1];

                        byte R = pixels[offset + 2];

                        byte A = pixels[offset + 3];

     

                        // convert to RGBA format for BitmapEncoder

                        pixels[offset] = R; // Red

                        pixels[offset + 1] = G; // Green

                        pixels[offset + 2] = B; // Blue

                        pixels[offset + 3] = A; // Alpha

                    }

                }

            }



    Friday, December 16, 2011 1:58 PM

All replies

  • Hi Irina, 
    You can convert BitmapSource to byte[] as follows:
    
    
    using System.Runtime.InteropServices.WindowsRuntime;
    
                byte[] pixeBuffer = null; 
    
                using (MemoryStream ms = new MemoryStream())
                {
                    WriteableBitmap wb = new WriteableBitmap(m_BitmapImage);
                    Stream s1 = wb.PixelBuffer.AsStream();
                    s1.CopyTo(ms);
    
                    pixeBuffer = ms.ToArray();
                }
    
    

    • Edited by Anton K2 Friday, December 16, 2011 11:38 AM
    Friday, December 16, 2011 11:33 AM
  • Hi Anton,

    Thanks for your answer.

    I found the solution for my issue in this way:

     

            public static async Task<byte[]> GetPhotoBytesAsync(BitmapImage bitmapImage)

            {

                if (bitmapImage == null)

                    return new byte[0] { };

     

                WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);

                Stream stream = writeableBitmap.PixelBuffer.AsStream();

                byte[] pixels = new byte[stream.Length];

                await stream.ReadAsync(pixels, 0, pixels.Length);

     

                ConvertToRGBA(writeableBitmap.PixelHeight, writeableBitmap.PixelWidth, pixels);

     

                InMemoryRandomAccessStream ims = new InMemoryRandomAccessStream();

                var imsWriter = ims.OpenWrite();

                await Task.Factory.StartNew(() => stream.CopyTo(imsWriter));

                stream.Flush();

                stream.Dispose();

     

                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ims);

                encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, (uint)writeableBitmap.PixelWidth, (uint)writeableBitmap.PixelHeight, 96, 96, pixels);

                await encoder.FlushAsync();

     

                stream = ims.OpenRead();

                byte[] pixeBuffer = new byte[ims.Size];

                await stream.ReadAsync(pixeBuffer, 0, pixeBuffer.Length);

                stream.Flush();

                stream.Dispose();

     

                ims.GetOutputStreamAt(0).FlushAsync().Start();

               

                return pixeBuffer;

            }

     

            private static void ConvertToRGBA(int pixelHeight, int pixelWidth, byte[] pixels)

            {

                if (pixels == null)

                    return;

     

                int offset;

                for (int row = 0; row < (uint)pixelHeight; row++)

                {

                    for (int col = 0; col < (uint)pixelWidth; col++)

                    {

                        offset = (row * (int)pixelWidth * 4) + (col * 4);

                        byte B = pixels[offset];

                        byte G = pixels[offset + 1];

                        byte R = pixels[offset + 2];

                        byte A = pixels[offset + 3];

     

                        // convert to RGBA format for BitmapEncoder

                        pixels[offset] = R; // Red

                        pixels[offset + 1] = G; // Green

                        pixels[offset + 2] = B; // Blue

                        pixels[offset + 3] = A; // Alpha

                    }

                }

            }



    Friday, December 16, 2011 1:58 PM
  • In my Windows 8 Version (Consumer Preview) the WriteableBitmap Class has a constructor with two Parameters:

    WriteableBitmap writeableBitmap = newWriteableBitmap(pixelwidth, pixelheigth);

    Maybe anyone can help me to convert a BitmapImage to byte in the Consumer Preview?

    Sunday, April 22, 2012 5:16 PM
  • I use this VB Code in a VB Metro App for Windows 8 Release Preview :

    ' Setup and launch the Open Picker
                Dim fileOpenPicker As New FileOpenPicker()
                fileOpenPicker.ViewMode = PickerViewMode.Thumbnail
                fileOpenPicker.FileTypeFilter.Add(".png")
                fileOpenPicker.FileTypeFilter.Add(".jpg")
    
                Dim files As IReadOnlyList(Of StorageFile) = Await fileOpenPicker.PickMultipleFilesAsync()
                Dim fileNames As New StringBuilder()
                           
                For Each file As StorageFile In files
                    ' At this point, the app can begin reading from the provided file
                    fileNames.AppendLine(file.Name)
    
                    Dim randomAccessStream = Await file.OpenReadAsync()
                    Dim dataReader = New DataReader(randomAccessStream)
                    Await dataReader.LoadAsync(randomAccessStream.Size)
                    Dim imageBytes(randomAccessStream.Size - 1) As Byte
                    dataReader.ReadBytes(imageBytes)
    
                    Dim p As Photo = Photos.CreatePhotos(0, imageBytes)
    
                Next

    • Proposed as answer by Cedric Bellec Sunday, June 17, 2012 4:11 PM
    Sunday, June 17, 2012 4:10 PM
  • I'm currently also in need of code to convert a BitmapImage into a byte array. Though I'm having trouble compiling your code. Which namespaces are you using?
    Thursday, December 27, 2012 6:59 PM