redcurry
redcurry

Reputation: 2497

Why am I getting an OutOfMemoryException from the Clipboard class?

I'm trying to use the System.Windows.Clipboard class to obtain an image from the clipboard:

var bitmapSource = System.Windows.Clipboard.GetImage();

When the image is copied via the PrintScreen key, it works fine. However, when the image is copied from a medical application, I get the following exception:

System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
   at System.Runtime.InteropServices.ComTypes.IDataObject.GetData(FORMATETC& format, STGMEDIUM& medium)
   at System.Windows.DataObject.OleConverter.GetDataInner(FORMATETC& formatetc, STGMEDIUM& medium)
   at System.Windows.DataObject.OleConverter.GetDataFromOleOther(String format, DVASPECT aspect, Int32 index)
   at System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert, DVASPECT aspect, Int32 index)
   at System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert)

The image pastes fine on Paint and Word, so the image is being copied properly to the clipboard. It's not a huge image, so I'm definitely not running out of memory. Any ideas?

Calling Clipboard.GetDataObject().GetFormats() returns the following:

{string[11]}
    [0]: "Rich Text Format"
    [1]: "MetaFilePict"
    [2]: "PNG+Office Art"
    [3]: "Office Drawing Shape Format"
    [4]: "DeviceIndependentBitmap"
    [5]: "Bitmap"
    [6]: "System.Drawing.Bitmap"
    [7]: "System.Windows.Media.Imaging.BitmapSource"
    [8]: "Format17"
    [9]: "EnhancedMetafile"
    [10]: "System.Drawing.Imaging.Metafile"

I tried Clipboard.GetData(format) for each of the formats above, and the only ones that returned a non-null object were "PNG+Office Art", "Office Drawing Shape Format", "Format17", and "EnhancedMetafile".

Upvotes: 4

Views: 1263

Answers (1)

Gabriel Luci
Gabriel Luci

Reputation: 40928

I believe your answer is here. In short:

the conclusion is that if you are working with the Clipboard in WPF and you are getting System.OutOfMemoryExceptions that don’t seem to make any sense, then you’ve probably forgotten to add the SerializableAttribute to whatever class you placed on the Clipboard.

So is this medical application your application? Because it would seem the problem is with how the image is put in the clipboard, rather than how the image is retrieved.

Update: Since it is not your application, then you will likely have to put up with their mistake (or the mistakes in Clipboard.GetData()). The source code of Clipboard.GetImage() is this:

public static Image GetImage() {
    var dataObject = Clipboard.GetDataObject();
    if (dataObject != null) {
        return dataObject.GetData(DataFormats.Bitmap, true) as Image;
    }

    return null;
}

Notice that your stack trace says that the exception happened in GetData(). Looking at the source code, that means that the call to GetDataObject() worked, which means you could (theoretically) use GetDataObject() yourself and convert the IDataObject from that into something you can use.

It might take some exploring to figure out what's going on. You might be able to use IDataObject.GetFormats() to inspect what it is, then use IDataObject.GetData() to get the data in that format.

Update 2: The solution from here points us in the right direction, but needs some modification:

var data = Clipboard.GetDataObject();
var ms = (MemoryStream) data.GetData("PNG+Office Art");

var image = Image.FromStream(ms)

Upvotes: 3

Related Questions