6

I'm trying to pass some representation of an image back and forth between Silverlight and a WCF service. If possible I'd like to pass a System.Windows.Media.Imaging.BitmapImage, since that would mean the client doesn't have to do any conversion.

However, at some point I need to store this image in a database, meaning the image representation must be able to convert to and from byte[]. I can create a BitmapImage from a byte[] by reading the array into a MemoryStream and using BitmapImage.SetSource(). But I can't seem to find a way to convert the other way - from BitmapImage to byte[]. Am I missing something obvious here?

If it helps at all, the conversion code could run on the server, i.e. it doesn't need to be Silverlight-safe.

goric
  • 11,491
  • 7
  • 53
  • 69
  • No. The image was initially being loaded via the user selecting it in an Open Dialog box. The workaround was to access openDialog.File.OpenRead, create a BinaryReader from that stream, then call ReadBytes() on the reader to get a byte[]. I haven't been keeping up with Silverlight 4, there may be a solution available now. – goric May 25 '10 at 02:20

3 Answers3

6

Use this:

public byte[] GetBytes(BitmapImage bi)
{
    WriteableBitmap wbm = new WriteableBitmap(bi);
    return wbm.ToByteArray();
}

Where

public static byte[] ToByteArray(this WriteableBitmap bmp)
{
    // Init buffer
    int w = bmp.PixelWidth;
    int h = bmp.PixelHeight;
    int[] p = bmp.Pixels;
    int len = p.Length;
    byte[] result = new byte[4 * w * h];

    // Copy pixels to buffer
    for (int i = 0, j = 0; i < len; i++, j += 4)
    {
        int color = p[i];
        result[j + 0] = (byte)(color >> 24); // A
        result[j + 1] = (byte)(color >> 16); // R
        result[j + 2] = (byte)(color >> 8);  // G
        result[j + 3] = (byte)(color);       // B
    }

    return result;
}
Julien Roncaglia
  • 17,397
  • 4
  • 57
  • 75
Vladimir Dorokhov
  • 3,784
  • 2
  • 23
  • 26
1

I had the same issue. I found the ImageTools library that makes thte job way easier.

Get the library and reference it and then

                        using (var writingStream = new MemoryStream())
                        {
                            var encoder = new PngEncoder
                            {
                                IsWritingUncompressed = false
                            };
                            encoder.Encode(bitmapImageInstance, writingStream);
                            // do something with the array
                        }
R4cOOn
  • 2,340
  • 2
  • 30
  • 41
0

Try using CopyPixels. You can copy the bitmap data to a byte array. However, I am honestly not sure what the format of the pixels would be...its probably dependent upon the kind of image that was originally loaded.

jrista
  • 32,447
  • 15
  • 90
  • 130
  • The page you linked to is for .NET in general, the Silverlight version of BitmapSource (in System.Windows.dll) doesn't support this method: http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapsource%28VS.95%29.aspx – goric Dec 05 '09 at 03:11
  • Oh, apologies. I forgot that Silverlight and WPF are not quite equal yet. – jrista Dec 05 '09 at 03:28