Bitmap.Save“通用错误”

当我运行我的应用程序时,出现以下错误:“在GDI +中发生了一个通用错误”。 我环顾四周,看到人们有类似的错误,但没有find真正的解决办法,或者实施起来真的很痛苦。 那些还没有得到解决scheme的人没有发布他们的代码。

所以我想我不妨试一试,然后抛出另一个关于如何解决这个错误的线索。 这是我的代码和错误

Random r = new Random(); DirectoryInfo di = new DirectoryInfo(folderbrowser.SelectedPath); FileInfo[] fi = di.GetFiles().Where(f => extensions.Contains(f.Extension.ToLower())).ToArray(); for (int i = 0; i < imageCount; i++) { int img1 = r.Next(imageCount); int img2 = r.Next(imageCount); while (img2 == img1) img2 = r.Next(imageCount); pic1.Image = Image.FromFile(fi[img1].FullName); pic2.Image = Image.FromFile(fi[img2].FullName); Image i1 = pic1.Image; Image i2 = pic2.Image; Bitmap bitmap = new Bitmap(i1.Width + i2.Width, 1080); using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawImage(i1, 0, 0); g.DrawImage(i2, i2.Width, 0); } bitmap.Save(@"C:\TEST\Image_"+i.ToString()); } 

这里是错误代码

 System.Runtime.InteropServices.ExternalException was unhandled Message=A generic error occurred in GDI+. Source=System.Drawing ErrorCode=-2147467259 StackTrace: at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) at System.Drawing.Image.Save(String filename, ImageFormat format) at System.Drawing.Image.Save(String filename) at WallpaperMerger.Form1.btn_merge_Click(Object sender, EventArgs e) in C:\Users\PeppeJ\documents\visual studio 2010\Projects\WallpaperMerger\WallpaperMerger\Form1.cs:line 113 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at WallpaperMerger.Program.Main() in C:\Users\PeppeJ\documents\visual studio 2010\Projects\WallpaperMerger\WallpaperMerger\Program.cs:line 18 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: 

那么你们在StackOverflow的想法呢? 我和其他人一样,必须input一个非常复杂的代码来解决这个问题,或者我犯了一个简单的错误,很容易纠正?

如果你想自己testing,如果这可能以某种方式帮助,这里有一个debugging版本的链接

只需勾选“使用多个文件”,select一个包含图像文件(C:\ Users \ Public \ Pictures \ Sample Pictures)的文件夹即可。 打合并。

我想补充一点,我在这个函数中使用Bitmap.Save,它完美的工作。

  Bitmap bitmap = new Bitmap(pic1.Image.Width + pic2.Image.Width, 1080); using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawImage(pic1.Image, 0, 0); g.DrawImage(pic2.Image, pic1.Image.Width, 0); } if (savepicfile.ShowDialog() == DialogResult.OK) bitmap.Save(savepicfile.FileName); 

在上面的函数中,文件是这样加载的:

  DialogResult result = pic1file.ShowDialog(); if (result == DialogResult.OK) pic1.Image = Image.FromFile(pic1file.FileName); 

值得一提的是“picX”是一个“System.Windows.Forms.PictureBox”对象。

根据我的经验,99%的错误是由以下两个问题中的一个造成的:

  1. 您没有写入文件的权限。
  2. 您正在尝试写入的文件被另一个进程锁定。

偶尔我碰到它时:

  • 我正在绘制GraphicPaths中的零点。
  • 我不是财产处理我的GDI +对象。 (可能与上面的选项2有关)

我会先检查前两件事。 如果这可以排除,我可以看到你没有正确处理你提供的代码中的几个对象。 我会清理的。 GDI +与.NET的GC没有特别的合作,如果你不打电话Dispose(),当你应该。

  var r = new Random(); var di = new DirectoryInfo(folderbrowser.SelectedPath); var fi = di.GetFiles().Where(f => extensions.Contains(f.Extension.ToLower())).ToArray(); for (var i = 0; i < imageCount; i++) { var img1 = r.Next(imageCount); var img2 = r.Next(imageCount); while (img2 == img1) { img2 = r.Next(imageCount); } pic1.Image = Image.FromFile(fi[img1].FullName); pic2.Image = Image.FromFile(fi[img2].FullName); var i1 = pic1.Image; var i2 = pic2.Image; using (var bitmap = new Bitmap(i1.Width + i2.Width, 1080)) using (var g = Graphics.FromImage(bitmap)) { g.DrawImage(i1, 0, 0); g.DrawImage(i2, i2.Width, 0); bitmap.Save(@"C:\TEST\Image_"+i.ToString()); } } 

编辑:更多的想法(嗯,真正的数字2以上澄清)…

  • 如果您的应用程序中有一个PictureBox或其他控件引用了您要编写的C:\TEST目录中的图像,则可以看到此错误。
  • 如果你有其他的代码读取你想要写入的图像,你可以看到这个错误。
  • 如果外部进程(如IDE,图像查看器/编辑器等)打开文件,则可以看到此错误。

调试思路:

  • 尝试在保存呼叫中设置中断点。 当你到达它时,使用这里发现的技巧来找出什么过程可能访问该文件: 如何找出哪个进程使用.NET锁定文件?
  • 首先尝试删除文件,看看它是否允许你保存,如果他们不是他们的。
  • 试着在你正在写的目录上设置“Everyone”的完整权限(尽管如此,不要这样)
  • 确保您试图保存的图像的宽度是大于零的数字。 我注意到你正在编程设置。
  • 确保你试图保存的图像的宽度不是很大(也许你遇到了内存问题?)

我找到了答案,目录“\ TEST \”不存在。 当我创建它,它完美无瑕。

我有这个确切的问题,什么修复它是包装在使用子句位图; 位图也需要处理

 using (Bitmap bmp = new Bitmap()) { // Bitmap operation } 

在处理Graphics对象之前先试着去做一下bitmap。

 Bitmap bitmap = new Bitmap(i1.Width + i2.Width, 1080); using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawImage(i1, 0, 0); g.DrawImage(i2, i2.Width, 0); bitmap.Save(@"C:\TEST\Image_"+i.ToString()); }