Добавить изображения в WinForm в ListView, выбрасывать OutOfMemory - PullRequest
0 голосов
/ 08 января 2020

Я хочу показать изображения с тегами GPS на форме. Пользователь нажимает на изображение, чем я показываю местоположение GPS из изображения в строке состояния. Я загрузил несколько файлов изображений (например, 40) и получил исключение - OutOfMemory. Файл jpeg имеет размер - 5 Мб, после Image.FromFile исчезают 50 Мб памяти. Пример: 1) запустить приложение - память - 50 МБ 2) выбрать 5 файлов изображений (25 МБ) - память - 316 МБ (!?) 3) щелкнуть изображение в ListView, вызвать событие listView1_SelectedIndexChanged, показать местоположение gps - память - 43 МБ (G * 1026) * сделал свою хорошую работу)

Как загрузить изображения без большой памяти?

Если я позвоню

image.Dispose();

после

imageList1.Images.Add(image);

в форме нет изображений

Код загрузки изображений:

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

Ответы [ 2 ]

0 голосов
/ 09 января 2020

Помимо ответа на то, что вы нашли, в идеале не следует загружать все изображения одновременно. Скажем, у вас есть 100 изображений для загрузки, если вы загружаете все изображения одновременно, вы рискуете получить исключение OOM.

В этом случае целесообразно использовать ленивый загрузочный механизм. Сначала загрузите, скажем, только 10 изображений, и, когда вы прокрутите вниз, загрузите оставшиеся 10 или любое другое допустимое число и удалите ранее загруженные 10.

0 голосов
/ 09 января 2020

Спасибо за комментарии. Благодаря им я нашел решение.

Решение - добавьте миниатюру вместо изображения

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);                
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...