GDI+ error with lots of PictureBoxes

C

Cruithne3753

I'm trying to create a Windows app with a clickable index of images
within a local folder.

Within a loop I've got:-

PictureBox pb = new PictureBox();
pb.Image = Image.FromFile(file);
....
pnlImageIndex.Controls.Add(pb);

Where "file" is the name of each file within a folder. They are all
GIFs, a number of them animated.

With more than 150 images, they all seem to load OK, but after a few
seconds I get this error thrown up:-


System.Runtime.InteropServices.ExternalException: A generic error
occurred in GDI+.
at System.Drawing.Image.SelectActiveFrame(FrameDimension dimension,
Int32 frameIndex)
at System.Drawing.ImageInfo.UpdateFrame()
at System.Drawing.ImageAnimator.UpdateFrames()
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at
System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,
Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)


And images start getting replaced with red outlined boxes with an X.

How do I get round this?

Thanks.

Matt
 
A

AlexS

Try to find out which gif causes that.

I believe some pic files can't be shown by .Net. Format issues or something
 
R

R. K. Wijayaratne

Hi,
From these lines:

at System.Drawing.Image.SelectActiveFrame(FrameDimension
dimension, Int32 frameIndex)
at System.Drawing.ImageInfo.UpdateFrame()
at System.Drawing.ImageAnimator.UpdateFrames()

It seems to be an error with the play-back of one of the animated GIFs
(ImageAnimator.UpdateFrames() and Image.SelectActiveFrame(...)).

If you run it in an empty directory and just add the animated GIFs one
by one to it you maybe able to pin-point which one the culprit is (it
may have got corrupted while orginally being compiled into an animated
GIF).

I am not sure if there is a method in .NET to determine if an animated
GIF is corrupt before it is loaded.

But either way you should have error handling built into the loading
as well as for the play-back sections of your code.

This may help you in this regard http://coding-help.blogspot.com/2007/07/catch-block-error-handling.html

RKW.
http://coding-help.blogspot.com/
 
C

Cruithne3753

Thanks Alexs and RKW, after a process of elimination I did find two GIFs
that seem to be causing the problem, pity there seems to be no
automated way of finding out which ones will fail.


I've already got a catch block in the loading code, but not sure to do
about the playback code, I don't really have any, PictureBox just seems
to animate itself automatically upon being visible...
 
R

R. K. Wijayaratne

Hi,

Here are a few things that you could try.

You can create a custom function which checks an animated GIF for
correctness before it is loaded. You can use use the
System.Drawing.Image.SelectActiveFrame method for this purpose, which
incidentally is the same method which throws the exception in your
stack trace above. I haven't used some of these methods before, but
here is something you can try:

1. Inside your loop, load the image using
System.Drawing.Image.FromFile method.

2. Check if it is an animated GIF and if so how many frames are in it
using the System.Drawing.Image.GetFrameCount method.

3. If it goes have more than one frame, then inside a try-catch block
loop through all the frames by calling the
System.Drawing.Image.SelectActiveFrame.

4. If an exception is thrown and caught here then you can warn the
user and not load that file.

See here for more information on System.Drawing.Image methods:

http://msdn2.microsoft.com/en-us/library/system.drawing.image.selectactiveframe.aspx


In terms of catching the exception during playback some
experimentation as to where the the try-catch block should be placed
maybe required.

5. You can use Visual Studio's (all editions) 'Break on Exception'
feature. Press 'Ctrl + Alt + E' to bring up the dialog and then check
the "Thrown" column of the "Common Language Runtime Exceptions" entry.
This will break whenever a .NET exception is thrown during debugging.
Remember to turn it off afterwards.

6. It also maybe possible for it to be caught inside on of the events
of the containing form. See below for more information on form events
(scroll down to 'Public Events')

http://msdn2.microsoft.com/en-us/library/system.windows.forms.form_members.aspx

7. Failing this you could place break point at the end of each method
in your class to see which ones gets hit first, and the place it there
(not the best approach).

After it is caught there are several things that you could do.

8. First it is not a crtical error. So you can just warn the user just
once as otherwise it can be annoying, log it if required and swallow
the exception and continue processing.

9. Secondly if you can get a handle to the specific problematic
PictureBox from the error information, you can warn the user and then
disable it.

RKW
http://coding-help.blogspot.com/
 
A

AlexS

As I missed previous post here is additional remark for "pity there seems to
be no automated way of finding out which ones will fail"

Use try-catch when loading pics, then you will be able to catch the
exception - same as automated way to find "bad" gifs. In future versions
they might work, but try block will save you further effort of finding ones
that do not.

HTH
Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top