88380

Bitmap.Save “Generic Error”

Question:

When I run my application the following error get's thrown in my face "A generic error occurred in GDI+." I've looked around and seen people have similar errors, but have found no real solution, or it is a real pain in the butt to implement. And those that have not gotten a solution have not posted their code.

So I thought I might as well give it a shot and throw another thread up about how to fix this error. This is my Code & Error

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()); }

And here's the Error code

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:

So what do you guys here at StackOverflow think. Am I the same boat as the others and have to type a ridiculously complex code to solve this problem, or have I made a simple mistake and it's easy to correct?

If you want to test it yourself if that might somehow help, here's a link to the <a href="https://dl.dropbox.com/u/14970061/WallpaperMerger.exe" rel="nofollow">Debug Build</a>

Simply tick "Use Multiple Files", select a folder containing image files (C:\Users\Public\Pictures\Sample Pictures) for instance. Hit Merge.

I'd like to add that I use Bitmap.Save in this function, and it works flawlessly.

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);

In the above function files are loaded like this:

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

Something else worth mentioning is that "picX" is a "System.Windows.Forms.PictureBox" object.

Answer1:

In my experience, 99% of the time this error is caused by an issue where either:

<ol><li>You don't have permission to write the file. </li> <li>The file you're trying to write to is locked by another process.</li> </ol>

Occasionally I've run into it when:

<ul><li>I'm drawing GraphicPaths with zero points in them.</li> <li>I'm not property disposing of my GDI+ objects. (possibly related to option 2 above)</li> </ul>

I'd check the first two things first. If that can be ruled out I can see where you're not properly disposing of a few objects in the code you provided. I'd clean that up. GDI+ isn't particularly cooperative with .NET's GC if you aren't calling Dispose() when you're supposed to.

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()); } } <hr />

<strong>EDIT: More ideas (Well, really clarification of number 2 above)...</strong>

<ul><li>If you have a PictureBox or other control in your app referencing the images in your C:\TEST directory that you're trying to write, you can see this error.</li> <li>If you have other code reading the image you're trying to write to you can see this error.</li> <li>If an external process, such as your IDE, an image viewer/editor, etc. has the file open you can see this error.</li> </ul>

Debugging ideas:

<ul><li>Try setting a break point on the Save call. When you get to it, use the tips found here to figure out what process might be accessing the file: <a href="https://stackoverflow.com/questions/317071/how-do-i-find-out-which-process-is-locking-a-file-using-net" rel="nofollow">How do I find out which process is locking a file using .NET?</a></li> <li>Try just deleting the files first to see if it allows you to save if they're not their.</li> <li>Try setting full permissions for "Everyone" on the directory you're writing to (Don't leave it like this, though)</li> <li>Make sure the width of the image you're trying to save is a number greater than zero. I noticed you're setting that programatically.</li> <li>Make sure the width of the image you're trying to save isn't ridiculously huge (an maybe you're running into a memory issue?)</li> </ul>

Answer2:

I found the answer, the directory "\TEST\" didn't exist. When I created it , it worked flawlessly.

Answer3:

I had this exact problem, and what fixed it was to wrap the Bitmap in the using clause; Bitmap needs to be disposed as well

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

Answer4:

Try doing the bitmap.Save before you dispose of the Graphics object:

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()); }

Recommend

  • Hatch area using pcolormesh in Basemap
  • Sum and Average of a series of numbers inputed to a text field
  • Spring MVC redirect with custom http headers
  • What dll is needed for Windows.Devices.Geolocation?
  • java.net.SocketTimeoutException on embedded tomcat with jersey
  • Why isn't \\\\ interpreted as a blackslash in this regex?
  • not able to create VC++ project, with VS11
  • Visual studio 2015 keystroke with mouse button
  • NRefactory: How do I access unresolved Named Arguments on a Property Attribute?
  • Send data from edittext to listview
  • Upgrade project from WorkLight 6.1 to MobileFirst 7.1
  • TFS - how do I sum child task hours to parent
  • Deploying a CodeRush plugin from the Community Site
  • How to pass solution folder as parameter in command line arguments (for debug)?
  • Jquery Mobile pageLoading() Method how does it work?
  • Does Apportable support to build library binary (.a/.so)?
  • ASP.NET MVC 2 Preview 2 - display directory list rather than home/index
  • Simulate click Geckofx vb,net
  • how to upload multiple files in c# windows application
  • How to handle images sent by a mobile device?
  • Do I need to reset a Perl hash index?
  • Android fill_parent issue
  • Using $this when not in object context
  • Nant, Vault & Windows Integrated Authentication
  • How do I fake an specific browser client when using Java's Net library?
  • How reduce the height of an mschart by breaking up the y-axis
  • Bug in WPF DataGrid
  • Sony Xperia Z Tablet not found by adb
  • VS2008 Enable C++ Exception with SEH
  • Perl system calls when running as another user using sudo
  • Javascript convert timezone issue
  • Why is the timeout on a windows udp receive socket always 500ms longer than set by SO_RCVTIMEO?
  • jquery mobile loadPage not working
  • jQuery tmpl and DataLink beta
  • How can I estimate amount of memory left with calling System.gc()?
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • Why winpcap requires both .lib and .dll to run?
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • How do you join a server to an Active Directory (domain)?
  • failed to connect to specific WiFi in android programmatically