0

I want to show images with gps tags on form. User click on image than I show gps location from the image on statusbar. I loaded some image files(for example, 40) and get exception - OutOfMemory. File jpeg have size - 5Mb, after Image.FromFile disappear 50 Mb memory. Example, 1) run application - memory - 50Mb 2) select 5 image files(25Mb) - memory - 316Mb(!?) 3) click on image in ListView,rise event listView1_SelectedIndexChanged, show gps location - memory - 43Mb(GC did his good job)

How do I load images without big memory?

If I call

image.Dispose();

after

imageList1.Images.Add(image);

there is no images on Form

Code load images:

OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
ofd.Filter = "Images (*.jpg, )|*.jpg";
ofd.Title = "Select files";
if (ofd.ShowDialog() != DialogResult.OK)
    return;

ListPathFoto.Clear();
foreach (string f in ofd.FileNames)
{
    ListPathFoto.Add(f);
}

imageList1.Images.Clear();
foreach (var oneFilePath in ListPathFoto)
{
    var image = Image.FromFile(oneFilePath);
    imageList1.Images.Add(image);
}

listView1.Clear();
listView1.View = View.LargeIcon;
imageList1.ImageSize = new Size(32, 32);
listView1.LargeImageList = imageList1;
for (int j = 0; j < imageList1.Images.Count; j++)
{
    ListViewItem item = new ListViewItem
    {
        ImageIndex = j
    };
    listView1.Items.Add(item);
}

step 1 step 2 step 3

  • 1
    It's [old](https://www.google.com/search?q=winforms+Images.Add+outofmemory+site%3Astackoverflow.com). When talking about images you forgot how they are presented in the memory (size of images matter), so your math is not really correct. This exception can also indicate corrupted image. Also note, that [Image](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image) has to be disposed. Hard to tell which from those issues is your. – Sinatr Jan 08 '20 at 15:31
  • 1
    See the comments I've left [here](https://stackoverflow.com/q/55348758/7444103). (Disposing of the disposable objects you create is not optional and, btw, `OpenFileDialog` is also a disposable object). – Jimi Jan 08 '20 at 15:49
  • Thank you for you suggestion. I am ashamed of the wrong google-ing of problem. I found two way - after loop with listView1.Items.Add(item) add GC.Collect(). And add mini-images to ListView as there [img.GetThumbnailImage](https://stackoverflow.com/questions/15584202/imagefrom-file-out-of-memory-exception) – Костя Гришин Jan 09 '20 at 03:45

2 Answers2

0

Thank you for comments. Thanks to them i found a solution.

Solution is - add Thumbnail instead Image

using (OpenFileDialog ofd = new OpenFileDialog())
{        
    ofd.Multiselect = true;
    ofd.Filter = "Файлы изображений (*.jpg, )|*.jpg";
    ofd.Title = "Выберите файлы изображений";

    if (ofd.ShowDialog() != DialogResult.OK)
        return;

    ListPathFoto.Clear();
    foreach (string f in ofd.FileNames)
    {
        ListPathFoto.Add(f);
    }
}

imageList1.ImageSize = new Size(32, 32);
imageList1.Images.Clear();
foreach (var oneFilePath in ListPathFoto)
{
    var image = Image.FromFile(oneFilePath);
    Image thumb = image.GetThumbnailImage(32, 32, () => false, IntPtr.Zero);
    imageList1.Images.Add(thumb);
    image.Dispose(); // important for clear memory
}

listView1.Clear();
listView1.View = View.LargeIcon;            
listView1.LargeImageList = imageList1;
for (int j = 0; j < imageList1.Images.Count; j++)
{
    ListViewItem item = new ListViewItem
    {
        ImageIndex = j
    };
    listView1.Items.Add(item);                
}
0

Apart from answer what you have found, ideally you should not be loading all images at once . Say you have 100 images to load, if you load all images at once you are at high risk of getting OOM exception .

In this case it is advisable to use lazy loading mechanism . Load only say 10 images at first and as you scroll down load remaining 10 or whatever the feasible number and dispose previously loaded 10 .

Praveen M
  • 443
  • 2
  • 11