Advertisement

06.20.2008 at 01:16AM PDT, ID: 23501493
[x]
Attachment Details

Image.GetThumbnailImage throws System.OutOfMemoryException in some cases.

Asked by Velio in C# Programming Language, Visual Studio .NET 2005, .NET Framework 2.0

Tags: Microsoft, Visual Studio 2005, C#, GDI+

Hi,

Here's some background info: I've got an app which interfaces with a scanner, saves the scanned pages as images in a user-specified format, does some processing on those images and "uploads" them to a remote database via a web-service.

If the processing of any of the images fails, the user is shown a dialog containing thumbnails of all the images, with the erroneous ones highlighted. The user can then choose to "skip" those images, so that they are not uploaded.

The problem occurs sometimes when the thumbnails are generated (inside a UserControl - code included below). If the files are TIFF files, the Image.GetThumbnailImage call (inside the Thumbnail helper class - code also included) throws an OutOfMemoryException, even when there are only a handful (2-5) images. If I change the format of the scanned files to PNG or JPEG, it generates the thumbnails properly.

I wrote a little test app which only uses the Thumbnail class to generate thumbnails. When I run the test app and the main app against the same set of images, the test app generated the thumbnails successfully (on my dev machine) but the main app fell over (on the production machine). Both machines have 2GB of memory but from what I've experienced and found on the web about GDI+, it seems it likes to throw the OutOfMemoryException for a whole range of reasons, not necessarily related to lack of memory.

Any ideas as to the cause and solution would be much appreciated.Start Free Trial
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
//USER CONTROL CODE
    public delegate void NoArgDelegate();
    public delegate void ImageArgDelegate(Image image);
 
    public partial class ScannedImageTile : UserControl
    {
        private ScannedFile _scannedFile;
        private Image _image;
        private static Size _thumbSize = new Size(72, 102);
        
        public ScannedImageTile()
        {
            InitializeComponent();
        }
 
        public ScannedFile ScannedFile
        {
            get { return _scannedFile; }
            set { 
                _scannedFile = value;
                if (_scannedFile == null)
                {
                    if (_image != null) _image.Dispose();
                    _image = null;
                    _pictureBox = null;
                }
                else
                {
                    _errorProvider.SetError(_pictureBox, _scannedFile.ErrorMessages);
                }
            }
        }
 
        private void GetThumbnail()
        {
            using (MemoryStream stream = new MemoryStream(_scannedFile.GetImageData()))
            {
                _image = Image.FromStream(stream);
            }
            Image thumb = Thumbnail.GetThumbnailImage(ref _thumbSize, _image);
            UpdatePictureSafely(thumb);
        }
 
        private void UpdatePictureSafely(Image thumb)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new ImageArgDelegate(UpdatePictureSafely), thumb);
            }
            else
            {
                _pictureBox.Image = thumb;
            }
        }
 
        private void ScannedImageTile_Paint(object sender, PaintEventArgs e)
        {
            if (_scannedFile != null && _pictureBox.Image == null)
                BeginInvoke(new NoArgDelegate(GetThumbnail));  
        }
    }
 
//THUMBNAIL HELPER CLASS CODE
    public class Thumbnail:ObjectModelBase
    {
        ...
        public static System.Drawing.Image GetThumbnailImage(ref Size thumbSize, System.Drawing.Image image)
        {
            System.Drawing.Image.GetThumbnailImageAbort myCallback =
                                  new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
 
            System.Drawing.Image thumb = image.GetThumbnailImage(thumbSize.Width, thumbSize.Height, myCallback, IntPtr.Zero);
            return thumb;
        }
 
        private static bool ThumbnailCallback()
        {
            return false;
        }
    }
 
Loading Advertisement...
 
[+][-]06.21.2008 at 04:29AM PDT, ID: 21837230

Assisted solutions are selected by the member who asked the question as a comment that contributed to their question's solution.

Start your 7-day free trial to view this Assisted Solution or ask the Experts your question.

 
[+][-]06.23.2008 at 01:08AM PDT, ID: 21844291

View this solution now by starting your 7-day free trial. Setting up your free trial is quick, easy, and secure. We will return you to this solution, unlocked, when you're done.

 

About this solution

Zones: C# Programming Language, Visual Studio .NET 2005, .NET Framework 2.0
Tags: Microsoft, Visual Studio 2005, C#, GDI+
Sign Up Now!
Solution Provided By: Velio
Participating Experts: 1
Solution Grade: A
 
 
 
Loading Advertisement...
20080716-EE-VQP-32 / EE_QW_2_20070628