0

I'm developing a control where user can set an image and i want this this to be as user friendly as possible - so support for copy & paste, drag & drop.

I've got this part working using IDataObjects, testing for fileformats of FileDrop, FileContents (eg from outlook), and bitmap eg:

private void GetImageFromIDataObject(IDataObject myIDO)
    {
        string[] dataformats = myIDO.GetFormats();

        Boolean GotImage = false;

        foreach (string df in dataformats)
        {
            if (df == DataFormats.FileDrop)
            {
              // code here
            }
            if (df == DataFormats.Bitmap)
            {
                // Source of my problem here... this gets & displays image but
                // how do I then convert from here ?
                ImageSource myIS = Utilities.MyImaging.ImageFromClipboardDib();
                ImgPerson.Source = myIS;
            }
         }
     }

The ImageFromClipboard code is Thomas Levesque's as referenced in the answer to this SO question wpf InteropBitmap to bitmap

http://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/

No matter how I get the image onto ImgPerson, this part is working fine; image displays nicely.

When user presses save I need to convert the image to a bytearray and send to a WCF server which will save to server - as in, reconstruct the bytearray into an image and save it in a folder.

For all formats of drag & drop, copy & paste the image is some form of System.Windows.Media.Imaging.BitmapImage.

Except for those involving the clipboard which using Thomas's code becomes System.Windows.Media.Imaging.BitmapFrameDecode.

If I avoid Thomas's code and use:

BitmapSource myBS = Clipboard.GetImage();
ImgPerson.Source = myBS;

I get a System.Windows.Interop.InteropBitmap.

I can't figure out how to work with these; to get them into a bytearray so I can pass to WCF for reconstruction and saving to folder.

Community
  • 1
  • 1
andrew
  • 1,184
  • 3
  • 19
  • 28

2 Answers2

0

Try this piece of code

    public byte[] ImageToBytes(BitmapImage imgSource)
    {
        MemoryStream objMS = new MemoryStream();        
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(imgSource));
        encoder.Save(objMS);
        return objMS.GetBuffer();
    }

You can also use JpegBitmapEncoder, BmpBitmapEncoder based on your requirements.

    byte[] arr = ImageToBytes(ImgPerson.Source as BitmapImage);
Nitesh
  • 7,261
  • 3
  • 30
  • 25
  • I previously tried BitmapImage myBI = ImgDriver.Source as BitmapImage and this resulted in null; so the cast didn't work. I can't test your answer till tomorrow but I suspect both options would still result in a null from the implicit cast ? – andrew Aug 05 '13 at 14:10
0

I can't believe I didn't see this SO question but the this is essentially the same as my question:

WPF: System.Windows.Interop.InteropBitmap to System.Drawing.Bitmap

The answer being:

BitmapSource bmpSource = msg.ThumbnailSource as BitmapSource;
MemoryStream ms = new MemoryStream();
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmpSource));
encoder.Save(ms);
ms.Seek(0, SeekOrigin.Begin);


System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(ms);

So similar in execution to Nitesh's answer but crucially, works with an inter-op bitmap.

Community
  • 1
  • 1
andrew
  • 1,184
  • 3
  • 19
  • 28