WPF/WinForms/GDI interop: converting a WriteableBi

2019-02-27 12:09发布

问题:

How can I convert a WPF WriteableBitmap object to a System.Drawing.Image?

My WPF client app sends bitmap data to a web service, and the web service needs to construct a System.Drawing.Image on that end.

I know I can get the data of a WriteableBitmap, send the info over to the web service:

// WPF side:

WriteableBitmap bitmap = ...;
int width = bitmap.PixelWidth;
int height = bitmap.PixelHeight;
int[] pixels = bitmap.Pixels;

myWebService.CreateBitmap(width, height, pixels);

But on the web service end, I don't know how to create a System.Drawing.Image from this data.

// Web service side:

public void CreateBitmap(int[] wpfBitmapPixels, int width, int height)
{
   System.Drawing.Bitmap bitmap = ? // How can I create this?
}

回答1:

this blog post shows how to encode your WriteableBitmap as a jpeg image. Perhaps that helps?

If you really want to transfer the raw image data (pixels) you could:

  1. create a System.Drawing.Bitmap with the correct size
  2. iterate over your raw data, convert the raw data to a System.Drawing.Color (e.g. via Color.FromArgb() and set each pixel color in the newly created image via SetPixel()

I'd definitely prefer the first solution (the one described in the blog post).



回答2:

If your bitmap data is uncompressed, you could probably use this System.Drawing.Bitmap constructor: Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr).

If the bitmap is encoded as jpg or png, create a MemoryStream from the bitmap data, and use it with the Bitmap(Stream) constructor.

EDIT:

Since you're sending the bitmap to a web service, I suggest you encode it to begin with. There are several encoders in the System.Windows.Media.Imaging namespace. For example:

    WriteableBitmap bitmap = ...;
    var stream = new MemoryStream();               
    var encoder = new JpegBitmapEncoder(); 
    encoder.Frames.Add( BitmapFrame.Create( bitmap ) ); 
    encoder.Save( stream ); 
    byte[] buffer = stream.GetBuffer(); 
    // Send the buffer to the web service   

On the receiving end, simply:

    var bitmap = new System.Drawing.Bitmap( new MemoryStream( buffer ) );

Hope that helps.



回答3:

The question is for WPF, and Pixels does not appear to be a property of WriteableBitmap. Some of the answers here point to SilverLight articles, so I suspect this might be a difference between WPF and SilverLight.