Почему я получаю OutOfMemoryException от класса Clipboard? - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь использовать класс System.Windows.Clipboard для получения изображения из буфера обмена:

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

Когда изображение копируется с помощью клавиши PrintScreen, оно работает нормально.Однако, когда изображение копируется из медицинского приложения, я получаю следующее исключение:

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)

Изображение отлично вставляется в Paint и Word, поэтому изображение правильно копируется в буфер обмена.Это не огромное изображение, поэтому у меня точно не хватает памяти.Любые идеи?

Вызов Clipboard.GetDataObject().GetFormats() возвращает следующее:

{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"

Я пробовал Clipboard.GetData(format) для каждого из приведенных выше форматов, и единственные, которые возвращали ненулевой объект, были"PNG + Офисное искусство", "Формат формы офисного чертежа", "Format17" и "EnhancedMetafile".

1 Ответ

0 голосов
/ 19 декабря 2018

Я полагаю, ваш ответ здесь .Вкратце:

вывод заключается в том, что если вы работаете с буфером обмена в WPF и получаете исключения System.OutOfMemoryException, которые, кажется, не имеют никакого смысла, то вы, вероятно, забыли добавитьSerializableAttribute для любого класса, который вы поместили в буфер обмена.

Так это медицинское приложение ваше приложение?Поскольку может показаться, что проблема связана с тем, как изображение помещается в буфер обмена, а не с тем, как изображение извлекается.

Обновление: Поскольку это не ваше приложение, то вы, скорее всего,приходится мириться со своей ошибкой (или ошибками в Clipboard.GetData()). Исходный код Clipboard.GetImage() таков:

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

    return null;
}

Обратите внимание, что ваша трассировка стека говорит, что исключение произошло в GetData().Глядя на исходный код, это означает, что вызов GetDataObject() сработал, а это значит, что вы (теоретически) можете использовать GetDataObject() самостоятельно и преобразовать IDataObject из этого вчто-то, что вы можете использовать.

Может потребоваться некоторое исследование, чтобы понять, что происходит.Возможно, вы сможете использовать IDataObject.GetFormats() для проверки того, что это такое, затем используйте IDataObject.GetData() для получения данных в этом формате.

Обновление2: Решение от здесь указывает нам правильное направление, но нуждается в некоторой модификации:

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

var image = Image.FromStream(ms)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...