locked
OutOfMemoryException RRS feed

  • Question

  • i have some pictureboxes which when i click i want their image to change.
    i have a string array where i store the path of the image files and then an other array where they are stored randomized.
    the picturebox takes its image from the second one.
    it worked gret when i had 6 pictureboxes but now with 12 i get an "OutOfMemoryException"
    how can i deal with that?
    that s all in vb2008
    Thursday, March 11, 2010 10:22 AM

Answers

  • You could use Imaging API to do reduce resolution. Also make sure to dispose of images you do not need - it is not optional.

    As to images remember they get unpacked as they are loaded. So 'small' 1 MB JPEG can take, say, 10 MB of memory.
    Considering Windows Mobile has 32 MB virtual memory limit per process that would cause OOM easily.

    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Marked as answer by warrentang Monday, March 15, 2010 6:38 AM
    Thursday, March 11, 2010 4:59 PM
  • Basically the main problem here is that the System.Drawing classes of the NETCF don't allow you to interact with such large amounts of bitmaps. The solution consists on invoking COM interfaces like IImagingFactory (http://msdn.microsoft.com/en-us/library/aa918428.aspx) that interacts with the native resources that are underlying a bitmap in a much more efficient way. So the ideal solution in your case would be for you to use COM Interoperability to interact with such classes.

    Now: precisely as in many other aspects of Mobile Programming, when it comes to program for COM Components or Platform Invoke, the (NON-Microsoft's) OpenNETCF's Smart Device Framework comes very handy. Indeed, they developed a wrapper around the COM Interfaces you need and by simply referencing their (freeware) libraries you can reach the same result without knowing the internal difficult details of the COM Interoperability.

    By using OpenNETCF's SDF classes from OpenNETCF.Drawing.Imaging namespace, specifically ImagingFactory, IImage, ImageInfo and IBitmapImage, you can use native memory instead of managed. In any case remember the limitation about Virtual Memory on Windows CE-based OS -- for example you can read http://blogs.msdn.com/raffael/archive/2009/11/16/basics-on-windows-ce-mobile-an-alternative-way-to-approach-the-memory-monster.aspx.

    Finally, kudos for the following code are not mine (forums link changed) -- anyway you may benefit:

        public partial class Form1 : Form
        {
            private string Filename3mp = "\\Pictures\\3mp.jpg";
            private string Filename2mp = "\\Pictures\\2mp.jpg";
            private string Filename1mp = "\\Pictures\\1mp.jpg";
            
            public Form1()
            {
                InitializeComponent();
            }
    
            private void menuItem1_Click(object sender, EventArgs e)
            {
                LaunchMultipleTest();
            }
    
            private void LaunchMultipleTest()
            {
                for (int i = 0; i < 1000; ++i)
                {
                    LaunchTest();
                }
            }
            
            private void LaunchTest()
            {
                string st = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
                string path = st.Substring(0, st.LastIndexOf("\\")) + Filename3mp;
    
                //try
                //{
                //    Bitmap bitmap = new Bitmap(path);
                //    pictureBox1.Image = bitmap;
                //    pictureBox2.Image = bitmap;
                //}
                //catch (OutOfMemoryException ex)
                //{
                //    MessageBox.Show(ex.Message, ex.ToString());
                //}
    
                /*OpenNETCF.Drawing.Imaging.*/
                ImagingFactory imagingFactory = new ImagingFactoryClass();
                /*OpenNETCF.Drawing.Imaging.*/
                IImage image = null;
                /*OpenNETCF.Drawing.Imaging.*/
                ImageInfo ii;
                /*OpenNETCF.Drawing.Imaging.*/
                IBitmapImage imageBitmap = null;
    
                try
                {
    
                    try
                    {
                        using (FileStream fs = new FileStream(path, FileMode.Open))
                        {
                            if (imagingFactory.CreateImageFromStream(new StreamOnFile(fs), out image) == 0)
                            {
                                image.GetImageInfo(out ii);
                                if ((ii.Width > pictureBox1.Width) || (ii.Height > pictureBox1.Height))
                                {
                                    imagingFactory.CreateBitmapFromImage(image,
                                                (uint)pictureBox1.Width,
                                                (uint)pictureBox1.Height,
                                                ii.PixelFormat,
                                                InterpolationHint.InterpolationHintDefault,
                                                out imageBitmap);
                                }
                                else
                                {
                                    imagingFactory.CreateBitmapFromImage(image,
                                                ii.Width,
                                                ii.Height,
                                                ii.PixelFormat,
                                                InterpolationHint.InterpolationHintDefault,
                                                out imageBitmap);
                                }
                            }
    
    
                        }
                    }
                    catch (OutOfMemoryException oomex)
                    {
                        //...
                        MessageBox.Show(oomex.Message);
                    }
                    finally //clean-up in any case
                    {
                        if (null != imagingFactory)
                            Marshal.FinalReleaseComObject(imagingFactory);
                        if (null != image)
                            Marshal.FinalReleaseComObject(image);
                    }
    
                    using (Bitmap bm = ImageUtils.IBitmapImageToBitmap(imageBitmap))
                    {
                        Utilities.ResizeBitmap(bm, pictureBox1);
                        Utilities.ResizeBitmap(bm, pictureBox2);
                    }
    
                }
                catch (OutOfMemoryException ex)
                {
                    MessageBox.Show(ex.ToString(), ex.Message);
                }
                finally
                {
                    if (null != imageBitmap)
                        Marshal.FinalReleaseComObject(imageBitmap);
                }
                
            }
        }
    
        public class Utilities
        {
    
            internal static bool ResizeBitmap(Bitmap bm, PictureBox pictureBox)
            {
                bool ret = false;
                try
                {
                    Bitmap resizedImage = new Bitmap(pictureBox.Width, pictureBox.Height);
                    using (Graphics gfx = Graphics.FromImage(resizedImage))
                    {
                        gfx.DrawImage(bm, new Rectangle(0, 0, pictureBox.Width, pictureBox.Height), new Rectangle(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel);
                    }
                    pictureBox.Image = resizedImage;
                    pictureBox.Refresh();
    
                    ret = true;
                }
                catch 
                {
                    //ret = false;
                }
                
                return ret;
    
            }
    
    
        }
    




    HTH!


    Thanks,
    ~raffaele
    http://blogs.msdn.com/raffael

    This posting is provided 'as is' with no warranties and confers no rights.
    • Marked as answer by warrentang Monday, March 15, 2010 6:38 AM
    Friday, March 12, 2010 2:53 PM

All replies

  • ok i just noticed that this happens with certain photos of a little higher resolution. is there a way i can maybe reduce their resolution in the program?
    Thursday, March 11, 2010 1:06 PM
  • You could use Imaging API to do reduce resolution. Also make sure to dispose of images you do not need - it is not optional.

    As to images remember they get unpacked as they are loaded. So 'small' 1 MB JPEG can take, say, 10 MB of memory.
    Considering Windows Mobile has 32 MB virtual memory limit per process that would cause OOM easily.

    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Marked as answer by warrentang Monday, March 15, 2010 6:38 AM
    Thursday, March 11, 2010 4:59 PM
  • Basically the main problem here is that the System.Drawing classes of the NETCF don't allow you to interact with such large amounts of bitmaps. The solution consists on invoking COM interfaces like IImagingFactory (http://msdn.microsoft.com/en-us/library/aa918428.aspx) that interacts with the native resources that are underlying a bitmap in a much more efficient way. So the ideal solution in your case would be for you to use COM Interoperability to interact with such classes.

    Now: precisely as in many other aspects of Mobile Programming, when it comes to program for COM Components or Platform Invoke, the (NON-Microsoft's) OpenNETCF's Smart Device Framework comes very handy. Indeed, they developed a wrapper around the COM Interfaces you need and by simply referencing their (freeware) libraries you can reach the same result without knowing the internal difficult details of the COM Interoperability.

    By using OpenNETCF's SDF classes from OpenNETCF.Drawing.Imaging namespace, specifically ImagingFactory, IImage, ImageInfo and IBitmapImage, you can use native memory instead of managed. In any case remember the limitation about Virtual Memory on Windows CE-based OS -- for example you can read http://blogs.msdn.com/raffael/archive/2009/11/16/basics-on-windows-ce-mobile-an-alternative-way-to-approach-the-memory-monster.aspx.

    Finally, kudos for the following code are not mine (forums link changed) -- anyway you may benefit:

        public partial class Form1 : Form
        {
            private string Filename3mp = "\\Pictures\\3mp.jpg";
            private string Filename2mp = "\\Pictures\\2mp.jpg";
            private string Filename1mp = "\\Pictures\\1mp.jpg";
            
            public Form1()
            {
                InitializeComponent();
            }
    
            private void menuItem1_Click(object sender, EventArgs e)
            {
                LaunchMultipleTest();
            }
    
            private void LaunchMultipleTest()
            {
                for (int i = 0; i < 1000; ++i)
                {
                    LaunchTest();
                }
            }
            
            private void LaunchTest()
            {
                string st = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
                string path = st.Substring(0, st.LastIndexOf("\\")) + Filename3mp;
    
                //try
                //{
                //    Bitmap bitmap = new Bitmap(path);
                //    pictureBox1.Image = bitmap;
                //    pictureBox2.Image = bitmap;
                //}
                //catch (OutOfMemoryException ex)
                //{
                //    MessageBox.Show(ex.Message, ex.ToString());
                //}
    
                /*OpenNETCF.Drawing.Imaging.*/
                ImagingFactory imagingFactory = new ImagingFactoryClass();
                /*OpenNETCF.Drawing.Imaging.*/
                IImage image = null;
                /*OpenNETCF.Drawing.Imaging.*/
                ImageInfo ii;
                /*OpenNETCF.Drawing.Imaging.*/
                IBitmapImage imageBitmap = null;
    
                try
                {
    
                    try
                    {
                        using (FileStream fs = new FileStream(path, FileMode.Open))
                        {
                            if (imagingFactory.CreateImageFromStream(new StreamOnFile(fs), out image) == 0)
                            {
                                image.GetImageInfo(out ii);
                                if ((ii.Width > pictureBox1.Width) || (ii.Height > pictureBox1.Height))
                                {
                                    imagingFactory.CreateBitmapFromImage(image,
                                                (uint)pictureBox1.Width,
                                                (uint)pictureBox1.Height,
                                                ii.PixelFormat,
                                                InterpolationHint.InterpolationHintDefault,
                                                out imageBitmap);
                                }
                                else
                                {
                                    imagingFactory.CreateBitmapFromImage(image,
                                                ii.Width,
                                                ii.Height,
                                                ii.PixelFormat,
                                                InterpolationHint.InterpolationHintDefault,
                                                out imageBitmap);
                                }
                            }
    
    
                        }
                    }
                    catch (OutOfMemoryException oomex)
                    {
                        //...
                        MessageBox.Show(oomex.Message);
                    }
                    finally //clean-up in any case
                    {
                        if (null != imagingFactory)
                            Marshal.FinalReleaseComObject(imagingFactory);
                        if (null != image)
                            Marshal.FinalReleaseComObject(image);
                    }
    
                    using (Bitmap bm = ImageUtils.IBitmapImageToBitmap(imageBitmap))
                    {
                        Utilities.ResizeBitmap(bm, pictureBox1);
                        Utilities.ResizeBitmap(bm, pictureBox2);
                    }
    
                }
                catch (OutOfMemoryException ex)
                {
                    MessageBox.Show(ex.ToString(), ex.Message);
                }
                finally
                {
                    if (null != imageBitmap)
                        Marshal.FinalReleaseComObject(imageBitmap);
                }
                
            }
        }
    
        public class Utilities
        {
    
            internal static bool ResizeBitmap(Bitmap bm, PictureBox pictureBox)
            {
                bool ret = false;
                try
                {
                    Bitmap resizedImage = new Bitmap(pictureBox.Width, pictureBox.Height);
                    using (Graphics gfx = Graphics.FromImage(resizedImage))
                    {
                        gfx.DrawImage(bm, new Rectangle(0, 0, pictureBox.Width, pictureBox.Height), new Rectangle(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel);
                    }
                    pictureBox.Image = resizedImage;
                    pictureBox.Refresh();
    
                    ret = true;
                }
                catch 
                {
                    //ret = false;
                }
                
                return ret;
    
            }
    
    
        }
    




    HTH!


    Thanks,
    ~raffaele
    http://blogs.msdn.com/raffael

    This posting is provided 'as is' with no warranties and confers no rights.
    • Marked as answer by warrentang Monday, March 15, 2010 6:38 AM
    Friday, March 12, 2010 2:53 PM