c# - 为什么我从 Clipboard 类中得到 OutOfMemoryException?
问题描述
我正在尝试使用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+Office Art”、“Office Drawing Shape Format”、“Format17”和“EnhancedMetafile”。
解决方案
我相信你的答案就在这里。简而言之:
结论是,如果您在 WPF 中使用剪贴板,并且您得到的 System.OutOfMemoryExceptions 似乎没有任何意义,那么您可能忘记将 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)
推荐阅读
- c# - Apache Ignite:如何缓存具有多个键的条目
- css - Django中的CSS SVG背景图像
- yaml - 连续 - 在 YAML 文件中
- flutter - 通过用户数据交换点寻找与服务器有关的命名法和架构理念
- spring-webclient - 如何关闭 netty 客户端 DNS 连接重试?
- html-email - OL Office 365 (Win 10) 邮件圈和边框问题
- python - 如何从匹配数据创建列?
- c++ - 如何将数据从 Firebase 推送到 Arduino?
- mysql - 当向组合表(Join table)插入值时,它将其他两个表值设为空 Spring JPA
- mysql - 从 Node.js 插入 MYSQL DB 的数据未定义