Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reading JPEG images gives Out Of Memory error

Status
Not open for further replies.

may1hem

Programmer
Jul 28, 2002
262
GB
I've written some code so that I can select images from the server to display on my web site. It works fine in folders with around 100 images but in one folder which has 400 images I get an Out Of Memory Error. It only reads 144 images then gives the error. Can someone help me find out how I can fix this? Should I be disposing of something in this loop? Or is something else causing the error?

-------------------------

Dim xdt2 As DataTable = myAdsFromXmlFile.Tables(0)
Dim foundRows() As DataRow
Dim dr As DataRow
Dim myCounter As Integer = 0
Dim myCurrentlyUsedImages As Integer = 0
Dim lsErrorLocation As String = ""

Try
lsErrorLocation = "#3#"
Label1.Text = ParentDirectory.GetFiles("*.jpg").Length.ToString

For Each myfile In ParentDirectory.GetFiles("*.jpg")
myCounter = myCounter + 1
dr = dt.NewRow()
fullpath = "/photos/" & Session("sesPhotoCategory") & "/" & Session("sesFolder") & "/" & myfile.Name
dr("image") = "/photos/" & Session("sesPhotoCategory") & "/" & Session("sesFolder") & "/" & myfile.Name
dr("fname") = myfile.Name

Dim currentImage As System.Drawing.Image = System.Drawing.Image.FromFile(myfile.FullName)
Dim imgWidth As Integer = currentImage.Width
Dim imgHeight As Integer = currentImage.Height
currentImage.Dispose()

dr("imgw") = imgWidth
dr("imgh") = imgHeight
dr("fsize") = myfile.Length / 1024
dr("fpath") = fullpath
foundRows = xdt2.Select("ImageUrl='" + fullpath + "'")
dr("chkd") = (foundRows.Length > 0)
If foundRows.Length > 0 Then
myCurrentlyUsedImages = myCurrentlyUsedImages + 1
End If
dr("loop") = myCounter
foundRows = xdt2.Select("ImageUrl='" + fullpath + "' AND Keyword='new'")
dr("keywordnew") = (foundRows.Length > 0)
dt.Rows.Add(dr)
Next

Catch Ex As Exception
Label2.Text = "Error occurred: " & Session("sesPhotoCategory") & " page, loop " & myCounter & ", " & Ex.Message & " // " & vbNewLine & lsErrorLocation
End Try
 
No, but I have 400 images stored in one category on the server, and this page is for me to select which of the 400 images I want to display on the live site.
 
there shouldn't be a need to load the image into memory to display a list of images. set the src attribute of the img tag to the url of the image and let the browser/web handle it for you.

also, you need to implement paging/filtering. loading 400 images at once will kill preformance no matter how to handle it.

I see you are getting the dimensions of the images. not sure why. but in any case, get this information when the image is uploaded and store it in a readily available location (database: rdbms or document). this will also increase through put because you won't be loading images every time just to get static information.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
The repeater (which is further down in the code) does just take the image URL and place that in an HTML image tag, so that's fine, just as you suggested.

I upload images just once per month, and so if it is slow for that one time it's not a big problem.

The reason that I'm loading each image into memory is so that I can read the image's dimensions.
----------------------
Dim currentImage As System.Drawing.Image = System.Drawing.Image.FromFile(myfile.FullName)
Dim imgWidth As Integer = currentImage.Width
Dim imgHeight As Integer = currentImage.Height
currentImage.Dispose()
----------------------
I want the code to read each image's dimensions on the fly rather than store the dimensions. I do sometimes overwrite an image and the image dimensions could have changed, and also the code checks to make sure the image size is correct as I occasionally forget to downsize an image before uploading, so this automatic check on the image size is essential. I do dispose of the image each time, so surely it's freeing up the memory on each loop? So why does it run out of memory?
 
garbage collection may not have freed the memory. calling dispose doesn't mean instance memory. it just marks the object for disposable so when CG does occur it can clean up the resources.

you should also using the [tt]using[/tt] keywork. this ensures Dispose is called even if an exception is thrown. as it stand now, Dispose is only called in Happy Days scenarios.
Code:
using(var image = Image.FromFile(...))
{
  height = image.Height;
  width = image.Width;
}
I would create an UI to upload the images it doesn't have to be a web ui, but it should capture the information you require. this way your reads perform much faster and only occur when the information actually changes. resist the urge to alter the data outside of the system which manages the data.

I come back to processing the information on writes instead of reads and page/filter the images as you select them.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
As I said, I upload images just once per month, and I load the page just once to select which images to use on the live site, so performance of loading this page once is not an issue.

I use an FTP client to upload images, which is convenient to upload a lot of images. I would rather keep things simple and use this FTP client rather than create a new uploader page and store in a database, which I'm not familiar with.

When you say I should create a UI, not necessarily a web ui, what do you mean? What else is there besides a web page?

I understand your point that each image loads into the server's memory, and even when I Dispose of it it actually isn't deleted until the server runs garbage collection. Can I force garbage collection after each 50 or 100 images are read?
 
When you say I should create a UI, not necessarily a web ui, what do you mean? What else is there besides a web page?
desktop
console
windows service which monitors a directory
etc.

Can I force garbage collection after each 50 or 100 images are read?
read up on GC. if you can force, then yes you could manage the memory consumption this way.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top