Picturebox population

Posts 110 of 10 · Page 1 of 1
Picturebox population
The program parses all images in a folder (~500+ images) and populates a picturebox for each image to display on the Panel interface using Panel.Control.Add (each image is 202x176, and the Panel supports vertical scrolling)

Program works fine, but my issue is RAM usage. With the numbers above, it can shoot up to 450k even after garbage collecting
Any ideas on how to improve RAM management while displaying all the images at once? I thought about rendering a segment of the images at a time, so like every time it scrolls down, the next segment renders and the previous segment unloads etc but I don't know if that's possible
Loading an image at runtime:
Code:
if(pictureBoxControl.Image == null) // Only load an image if one hasn't been loaded yet
{
	pictureBoxControl.Image = Image.FromFile(@"C:\Path\To\Image.png"); // Load from file
}
For unloading:
Code:
if(pictureBoxControl.Image != null) // Only unload if there was an image
{
	pictureBoxControl.Image.Dispose();  // Dispose of the memory
	pictureBoxControl.Image = null;
}
Determining when and what to load is up to you. Good luck
Quote Originally Posted by Hell_Demon View Post
Loading an image at runtime:
Code:
if(pictureBoxControl.Image == null) // Only load an image if one hasn't been loaded yet
{
	pictureBoxControl.Image = Image.FromFile(@"C:\Path\To\Image.png"); // Load from file
}
For unloading:
Code:
if(pictureBoxControl.Image != null) // Only unload if there was an image
{
	pictureBoxControl.Image.Dispose();  // Dispose of the memory
	pictureBoxControl.Image = null;
}
Determining when and what to load is up to you. Good luck
about the unloading 'if' check
code will crash if image is disposed but not null
I think u should do sth like this:

Code:
if(control.Image != null {
 if(!control.Image.IsDisposed) {
  // dispose
 }

 // null
}
Quote Originally Posted by Hell_Demon View Post
Loading an image at runtime:
Code:
if(pictureBoxControl.Image == null) // Only load an image if one hasn't been loaded yet
{
	pictureBoxControl.Image = Image.FromFile(@"C:\Path\To\Image.png"); // Load from file
}
For unloading:
Code:
if(pictureBoxControl.Image != null) // Only unload if there was an image
{
	pictureBoxControl.Image.Dispose();  // Dispose of the memory
	pictureBoxControl.Image = null;
}
Determining when and what to load is up to you. Good luck
Could have worded it better my bad. My problem is not how to unload an image, but rather a way to tell whether the picturebox control is in the user's view or not, so just like you said, the question is "when and what to load".

This is a view of the program, by scrolling you will find more images (All the images are loaded, which is why the RAM usage is high, that's why I'm asking if there is a more efficient way to do it.) https://prnt.sc/i5ezla
Maybe you can use panel1.VerticalScroll.Value in that case, if you used a custom scroll bar.
too lazy to write example code at the moment, but it shouldn't be all too difficult
Code:
box.Bounds.IntersectsWith(panel.ClientRectangle)
Will tell you if the control is currently visible somewhere inside the scrollable control
Sweet, thanks for the help. I've ended up writing the following code on the scroll event. In case somebody needs it in the future:

Code:
foreach (PictureBox ImageControl in PanelBody.Controls)
{
			if (ImageControl.Bounds.IntersectsWith(PanelBody.ClientRectangle))
			{
				if (!VisiblePictureBoxList.Contains(ImageControl)) //A check to ease the UI rendering
                                //Removing it has no effect on the functionality.
				{
					VisiblePictureBoxList.Add(ImageControl);
					ImageControl.Image = Image.FromFile(@"Image Path");
				}
			}
			else
			{
				if (ImageControl.Image != null)
				{
					ImageControl.Image = null;
					if (VisiblePictureBoxList.Contains(ImageControl))
					{
						VisiblePictureBoxList.Remove(ImageControl);
					}
				}
				GC.Collect();
			}
		}
Edit: Is there a different efficient way for it to be done? Iterating through all the Picturebox controls inside of a Panel on every scroll instance does not sound like the best solution to me, any ideas?
Quote Originally Posted by Mayion View Post
Edit: Is there a different efficient way for it to be done? Iterating through all the Picturebox controls inside of a Panel on every scroll instance does not sound like the best solution to me, any ideas?
Yes, I suggest you to have a static amount of picture boxes and move the ones that get scrolled out of view to the opposite site and have them reload the new images

Also, calling GC.Collect() inside a loop might not be the best thing to do..
Quote Originally Posted by Biesi View Post


Yes, I suggest you to have a static amount of picture boxes and move the ones that get scrolled out of view to the opposite site and have them reload the new images

Also, calling GC.Collect() inside a loop might not be the best thing to do..
Yeah, that was the first thought I had in mind, but I'm trying to provoke/test most UI scenarios for learning, and having an infinite panel controls is one of those tests that I prefer to take on rather than changing completely.
And gc was already removed from the loop as I went over the code for a redo.
You could calculate the virtual height of the images in the form of "total images / amount per row * (image height + padding)", then based on how far along the scrollbar is make a rough guess as to how far along you should start processing.

With 500 images in a 5 by x grid, at 50 px per image and 25 px spacing you'd get a height of 100 * 75 = 7500 px, substract the physical height of the viewport, since you won't be able to scroll beyond the last images.
As example we could use 500 px height.

Then the index you need to process/load would be between 7000 * scrollbar percentage, say you're scrolled to 50% then you'd be around 3500 px in. give or take half the viewport would be 3250 / 75 = 43.3, so start loading from row 43 until twice the viewport(4250/75 = 56.6, so load until 57)

It's early in the day, so excuse me if I made any errors in the above.

Edit: The above combined with the check to see if it intersects with the viewport would be pretty smooth loading I guess.
Posts 110 of 10 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?