Monday, November 1, 2010

Moonlight WritableBitmap and System.Drawing.Bitmap

A recent project required that I write a Moonlight client for an existing WCF service. This WCF service returned image information as System.Drawing.Bitmap rather than a url which a web client could use.

Now I could have just saved the image to a MemoryStream and then set a BitmapImage.StreamSource to be that stream, but I wanted to know if I could use a WritableBitmap to do the work rather than creating a new BitmapImage each time I get a image from the WCF service.


public static bool Convert(System.Drawing.Image image, ref WriteableBitmap _writableBitmap)
       {
            try
               {
                   if (_writableBitmap == null)
                   {                  
                      _writableBitmap = new WriteableBitmap((int)image.Width, (int)image.Height);
                   }
                   System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)image;              
                   System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
                   System.Drawing.Imaging.BitmapData bitmapData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                   try
                   {                               
                    int cnt = bmp.Width * bmp.Height * 4 / 4;
                    System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, _writableBitmap.Pixels, 0, cnt);                    
                   }
                   finally
                   {
                    bmp.UnlockBits(bitmapData);
                   }
                   return true;
                 }
                 catch
                 {
                   return false;
                 }
       }
As it turns out the code to put the data from a 32bit bitmap into a Writeablebitmap is quiet simple :)