locked
System.OutOfMemoryException: Out of memory. when resizing multiple images RRS feed

  • Question

  • User192985886 posted

    Hello all,

    I have the following code which runs through an SQL DB to resize image files stored to disk.  The original images are anywhere from 50k to 30mb.  After going through the first 75 items, or about 500 images, I get an out of memory error.

     

    My code is as follows:

     

    Dim imageFile As String = "test.jpg"
            Dim imageDir As String = Server.MapPath("~/admin/images/")
            Dim newWidth As Integer = 75
            Dim newHeight As Integer = 90
            Dim imageCount As Integer
            Dim strConnString As String = ConfigurationManager.ConnectionStrings("mlreddbConnectionString").ConnectionString
            Dim objConn As New SqlConnection(strConnString)
    
            '2. Create a command object for the query
            Dim strSQL As String = "SELECT * FROM tblHomePhoto"
    
            Dim objCmd As New SqlCommand(strSQL, objConn)
            objConn.Open()
            Dim rdr As SqlDataReader = objCmd.ExecuteReader
    
            While rdr.Read
    
                imageFile = rdr("txtPhotoName")
                If InStr(imageFile, ".") Then
                    imageDir = String.Format("~/images/propertyImages/{0}/", rdr("PropertyID"))
    
                    Dim trgDir As String = Server.MapPath(imageDir)
    
                    Dim origBMP As System.Drawing.Bitmap = System.Drawing.Bitmap.FromFile(trgDir + imageFile)
                    If origBMP.Width > origBMP.Width Then
                        newWidth = 397
                        newHeight = 245
                    Else
                        newWidth = 245
                        newHeight = 397
    
                    End If
                    
    
                    Dim newBMP As System.Drawing.Bitmap = New System.Drawing.Bitmap(origBMP, newWidth, newHeight)
                    Dim objGra As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newBMP)
    
                    objGra.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias
                    objGra.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
                    objGra.DrawImage(origBMP, 0, 0, newWidth, newHeight)
    
                    origBMP.Dispose()
                    newBMP.Save(trgDir + imageFile, System.Drawing.Imaging.ImageFormat.Jpeg)
                    newBMP.Dispose()
                    objGra.Dispose()
                    imageCount = imageCount + 1
                    System.GC.Collect()
    
                End If
            End While


     

    Out of memory. 
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.OutOfMemoryException: Out of memory.
    
    Source Error: 
    
    
    Line 27:                 Dim trgDir As String = Server.MapPath(imageDir)
    Line 28: 
    Line 29:                 Dim origBMP As System.Drawing.Bitmap = System.Drawing.Bitmap.FromFile(trgDir + imageFile)
    Line 30:                 If origBMP.Width > origBMP.Width Then
    Line 31:                     newWidth = 397
     
    
    Source File: C:\Inetpub\wwwroot\mountainluxury\Admin\images\Default.aspx.vb    Line: 29 
    
    Stack Trace: 
    
    
    [OutOfMemoryException: Out of memory.]
       System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement) +379537
       System.Drawing.Image.FromFile(String filename) +6
       admin_images_Default.Page_Load(Object sender, EventArgs e) in C:\Inetpub\wwwroot\mountainluxury\Admin\images\Default.aspx.vb:29
       System.Web.UI.Control.OnLoad(EventArgs e) +99
       System.Web.UI.Control.LoadRecursive() +50
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
    
     
    
    
    --------------------------------------------------------------------------------
    Version Information: Microsoft .NET Framework Version:2.0.50727.3603; ASP.NET Version:2.0.50727.3082 


     

    Wednesday, March 10, 2010 11:40 AM

Answers

  • User-525215917 posted

    Be very careful with image processing on server-side. Make sure you clean-up all resources right after you don't need them. And also make sure you handle exceptions correctly. Don't let exceptions break your methods run before you have disposed all disposable objects and released all unmanaged resources.

    As you may have faulty images your current code is open to memory wasting because I can see no exception handling there. You should also use using() blocks for disposable objects so they get disposed automatically.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, March 14, 2010 4:53 AM

All replies

  • User665034424 posted

    OutOfMemoryException is thrown in many scenarios other than running out of memory.

    Check file persmissions. If it does'nt resolve, check for badly compressed image file, when tring to uncompress these files can cause lots of memory issues. Remove the file thats being processed while the exception is thrown and run the application again.

    Another problem with Image.FromFile is it leaves the file handle open eve if you Dispose() it. Means garbage collection must happen then only the object will go of from memory. Forcing a garbage collection to happen is bad practice. So if you App runs for a time and opens a lot of files consider using Image.FromStream() instead.


    Wednesday, March 10, 2010 12:17 PM
  • User-37275327 posted

    You better check System's memory consumption from the task bar while running this application. May be whole memory is occupied by the image weights.


    Wednesday, March 10, 2010 12:21 PM
  • User532898053 posted

    You could try setting your image references to equal Nothing so the garbage collector can collect them. e.g. the end of your code snippet could be:

    origBMP.Dispose()  
    origBMP = Nothing
    newBMP.Save(trgDir + imageFile, System.Drawing.Imaging.ImageFormat.Jpeg)  
    newBMP.Dispose()  
    newBMP = Nothing
    objGra.Dispose()
    objGra = Nothing 
    imageCount = imageCount + 1  
    System.GC.Collect()  


    see link for explanation:

    http://msdn.microsoft.com/en-us/library/8th8381z.aspx

    Wednesday, March 10, 2010 12:28 PM
  • User192985886 posted

    I think it was a problem with an image file.  I simply put in an ON ERROR RESUME NEXT and it moved past and re-sized the rest of my files. 

    Wednesday, March 10, 2010 12:56 PM
  • User665034424 posted

    Exactly, even i suspected the same. Nice to see you have resolved problem yourself.


    Wednesday, March 10, 2010 1:02 PM
  • User-525215917 posted

    Be very careful with image processing on server-side. Make sure you clean-up all resources right after you don't need them. And also make sure you handle exceptions correctly. Don't let exceptions break your methods run before you have disposed all disposable objects and released all unmanaged resources.

    As you may have faulty images your current code is open to memory wasting because I can see no exception handling there. You should also use using() blocks for disposable objects so they get disposed automatically.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, March 14, 2010 4:53 AM