C# bitmap保存时GDI+出现一般性错误?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# bitmap保存时GDI+出现一般性错误?相关的知识,希望对你有一定的参考价值。
我自己构造了一个位图,通过GetBitMap获取,注:不是从文件中获取,是自己画的,然后想把它保存到文件中去,结果就出现错误了,文件夹的写权限也获取了,重新再构造的方法也试了,依然有这个错误;image.Save的几种格式也都试过了。崩溃ing!!用的是win7的系统,VS2017版,求大神给解决方法。
参考技术A printf()函数中的格式串格式为:[标志][输出最小宽度][.精度]类型。其中:方括号[]中 参考技术B 代码共享来调试追问工程有点大,bitmap的获取应该是没什么问题,打印功能都可以正常调用,就是存储的时候要报错
追答filename是什么内容
追问saveDlg是保存对话框的实例化,Filename是它的保存路径加保存的文件名
追答把重现问题的源码发来调试
追问BitMap bitMap;
SaveFileDialog saveDlg=new SaveFileDialog();
if (saveDlg.ShowDialog()==DialogResult.OK)
bitMap=Program.mainform.GetBitmap();//这个位图确定没问题的
bitMap.Save(saveDlg.FileName);
System.Drawing.Bitmap.GetHicon() 上的 GDI 对象泄漏
【中文标题】System.Drawing.Bitmap.GetHicon() 上的 GDI 对象泄漏【英文标题】:GDI Object leak on System.Drawing.Bitmap.GetHicon() 【发布时间】:2021-06-20 10:08:06 【问题描述】:我见过类似的问题,但没有一个能满足我的情况。
我正在修复 C++ Windows 窗体应用程序上的 GDI 对象泄漏。
这是它抛出的异常:
GDI+ 中出现一般错误。在 System.Drawing.Bitmap.GetHicon()
这是发生崩溃的那一行的GetHicon
调用:
this->notifyIcon1->Icon=Icon->FromHandle(((Bitmap^)imgsApp->Images[0])->GetHicon());
在这里做了一些阅读之后,在https://docs.microsoft.com/en-us/dotnet/api/system.drawing.icon.fromhandle?view=net-5.0 上,我看到我需要调用DestroyIcon()
以释放图标句柄(不确定这里的措辞是否正确),但我在这样做时遇到了麻烦熟悉 Windows 窗体。
【问题讨论】:
您链接到的文档字面上显示了使用DestroyIcon()
的示例。 Bitmap::GetHIcon()
的文档也是如此
相关/复制:Icon.FromHandle: should I Dispose it, or call DestroyIcon?
【参考方案1】:
试试这个:
IntPtr iconHandle = ((Bitmap^)imgsApp->Images[0])->GetHicon();
Icon ^newIcon = Icon::FromHandle(iconHandle);
this->notifyIcon1->Icon = (Icon^) newIcon->Clone();
newIcon->Dispose();
DestroyIcon((HICON)iconHandle.ToPointer());
每Icon.FromHandle: should I Dispose it, or call DestroyIcon?:
结论:Icon.FromHandle之后,ownHandle字段为false,因此Dispose/FromHandle不会调用DestroyIcon
因此:如果您使用 Icon.FromHandle 创建一个图标,您将不得不 Dispose() 该图标以及调用 DestroyIcon,正如备注部分所述
【讨论】:
我看到你做了什么,这应该可以工作,但是我得到:标识符“tempManagedRes”未定义。我想这必须在此之前定义? 感谢您的更新。在您的示例中初始化的 iconHandle 在第一行获取 HICON,但是在调用 DestroyIcon(iconHandle) 时会导致以下错误:没有合适的从“System::IntPtr”到“HICON”的转换函数存在 @ErnestoJorgeBitmap::GetHIcon()
返回 IntPtr
而不是 HICON
(分别是 struct HICON__*
或 void*
,具体取决于 STRICT
是否启用)。您必须调用DestroyIcon()
的实际 Win32 API C 声明,而不是它的 PInvoke 版本。您将不得不使用类型转换,例如 DestroyIcon((HICON)iconHandle);
(我不使用 Managed C++)。
类型转换的结果相同,因为没有从 IntPtr 到 HICON 的转换。这与文档link 不匹配,因为他们调用destroyIcon(newIcon->Handle)
并且在我的代码中执行此操作也会导致“没有合适的转换”。如果Bitmap::GetHicon()
返回一个 IntPtr,文档如何调用DestroyIcon()
?一旦发现其他内容,我将继续研究并更新。
@ErnestoJorge Icon::Handle
也是 IntPtr
。该文档显示的是 C# 中的代码示例,而不是 C++ 中的代码示例(C# 中没有 ->
运算符),其中 DestroyIcon()
是通过使用 IntPtr
参数的 PInvoke 调用的。在 C++ 中,尝试使用IntPtr::ToPointer()
,例如:DestroyIcon((HICON)iconHandle.ToPointer());
以上是关于C# bitmap保存时GDI+出现一般性错误?的主要内容,如果未能解决你的问题,请参考以下文章
使用带有内存流的 c# 在控制台应用程序中保存图像时,GDI + 中发生一般错误
c#中利用system.timers多线程做图像处理,图像保存时提示“GDI+ 中发生一般性错误”,如何解决?