Catching and Processing GDI+ Exception
-
Be kind please. The simple C# program below runs correctly until it encounters a "generic error in GDI+" exception. This seems to happen about 500 images into the list, regardless of the actual image data. I have several questions here, insight to any are appreacited. My intent is to use the GDI+ routines to get basic image properties (width and height) from directories containing images. I can't find any smoking gun in the exception data. The error code is -2147467259. Thanks in advance for any direction. Q1) What is really going wrong here? I can catch the execption, but I don't know what to do with it. Q2) Correctness and functionality is more important; but isn't there a more efficicent way to do this without a creating a new Bitmap object inside the inner loop?
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace ListFiles1 { class Program { static void Main(string[] args) { Console.WriteLine("This program lists all the files in the directory"); System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(@"c:\image"); foreach (System.IO.FileInfo file in dir.GetFiles("*.jpg")) { Bitmap myBitmap = new Bitmap(file.DirectoryName + @"\" + file.Name); Console.WriteLine("{0}, {1}, {2}, {3}", file.Name, file.Length, myBitmap.Width, myBitmap.Height); } Console.ReadLine(); } } }
-
Be kind please. The simple C# program below runs correctly until it encounters a "generic error in GDI+" exception. This seems to happen about 500 images into the list, regardless of the actual image data. I have several questions here, insight to any are appreacited. My intent is to use the GDI+ routines to get basic image properties (width and height) from directories containing images. I can't find any smoking gun in the exception data. The error code is -2147467259. Thanks in advance for any direction. Q1) What is really going wrong here? I can catch the execption, but I don't know what to do with it. Q2) Correctness and functionality is more important; but isn't there a more efficicent way to do this without a creating a new Bitmap object inside the inner loop?
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace ListFiles1 { class Program { static void Main(string[] args) { Console.WriteLine("This program lists all the files in the directory"); System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(@"c:\image"); foreach (System.IO.FileInfo file in dir.GetFiles("*.jpg")) { Bitmap myBitmap = new Bitmap(file.DirectoryName + @"\" + file.Name); Console.WriteLine("{0}, {1}, {2}, {3}", file.Name, file.Length, myBitmap.Width, myBitmap.Height); } Console.ReadLine(); } } }
Hi, are you sure it is 2147467259 and not -2147467259 ??? that one equals 0x80004005 which is simply good old E_FAIL GDI+ is very good at error handling, everything is called "general error" and the error number does not tell anything. In your case you are running out of memory. Didn't they tell you you should Dispose of all objects you no longer need when such objects are instances of a class that offers a void Dispose() method ? You are polluting your entire system! :)
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Hi, are you sure it is 2147467259 and not -2147467259 ??? that one equals 0x80004005 which is simply good old E_FAIL GDI+ is very good at error handling, everything is called "general error" and the error number does not tell anything. In your case you are running out of memory. Didn't they tell you you should Dispose of all objects you no longer need when such objects are instances of a class that offers a void Dispose() method ? You are polluting your entire system! :)
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Luc Pattyn wrote:
In your case you are running out of memory. Didn't they tell you you should Dispose of all objects you no longer need when such objects are instances of a class that offers a void Dispose() method ?
I guess I am naive to think that C# garbage collection would "just work". More likely this is my problem for using GDI+ within C#. So the challenge for me remains to either: a) Reuse a single instance of myBitmap. b) Invoke the Dispose() method so too many objects don't overrun the heap. I'm not sure I know how to do either, but will try.
-
Luc Pattyn wrote:
In your case you are running out of memory. Didn't they tell you you should Dispose of all objects you no longer need when such objects are instances of a class that offers a void Dispose() method ?
I guess I am naive to think that C# garbage collection would "just work". More likely this is my problem for using GDI+ within C#. So the challenge for me remains to either: a) Reuse a single instance of myBitmap. b) Invoke the Dispose() method so too many objects don't overrun the heap. I'm not sure I know how to do either, but will try.
Getting a mysterious error message is a good indication naivety has to be scaled back. Invoking a method with no parameters and no return value is rather easy, reusing a Bitmap does not sound like a good idea.
ss42a wrote:
I'm not sure I know how
Then that's why they invented "documentation", available under either MSDN or Google. :)
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
Luc Pattyn wrote:
In your case you are running out of memory. Didn't they tell you you should Dispose of all objects you no longer need when such objects are instances of a class that offers a void Dispose() method ?
I guess I am naive to think that C# garbage collection would "just work". More likely this is my problem for using GDI+ within C#. So the challenge for me remains to either: a) Reuse a single instance of myBitmap. b) Invoke the Dispose() method so too many objects don't overrun the heap. I'm not sure I know how to do either, but will try.
The next likely cause for a GDI+ general error is a bad image file. Suggestion: log the files one by one before creating the new Bitmap and/or show the filename in the catch construct. The (last) one shown is the suspicious one; try loading just that one; or try double-clicking it. BTW: IIRC GDI+ can't handle 1-bit-per-pixel images. :)
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
-
The next likely cause for a GDI+ general error is a bad image file. Suggestion: log the files one by one before creating the new Bitmap and/or show the filename in the catch construct. The (last) one shown is the suspicious one; try loading just that one; or try double-clicking it. BTW: IIRC GDI+ can't handle 1-bit-per-pixel images. :)
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google
Thank you! It turns out that some JPEG image files; which look fine as thumnails, display correctly; may have some kind of defect that causes GDI+ to throw an error. This is good, since I'm using the try/catch blocks to isolate them. Thank you for your help. Below is the modified code which works fine; but coughs up an occasional image file that may look fine, but has some internal defect that confuses the GDI+ decoder.
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace ListFiles1 { class Program { static void Main(string[] args) { System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(@"c:\image"); foreach (System.IO.FileInfo file in dir.GetFiles("*.jpg")) { try { Bitmap myBitmap = new Bitmap(file.FullName); Console.WriteLine("{0}, {1}, {2}, {3}", file.Name, file.Length, myBitmap.Width, myBitmap.Height); myBitmap.Dispose(); } catch (Exception e) { Console.WriteLine("*************** Exception Caught for {0}", file.FullName); Console.WriteLine(e.Message); //Console.WriteLine(e.StackTrace); //throw; } } Console.WriteLine("Any character to exit..."); Console.ReadLine(); } } }