Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
3 / 3 / 3
Регистрация: 24.05.2017
Сообщений: 32
.NET 4.x

Переполнение памяти при работе с изображениями

20.06.2018, 23:30. Показов 5311. Ответов 27

Студворк — интернет-сервис помощи студентам
Суть проблемы такова:
Имеется код для отображения изображений на panel и дальнейшей работы с ними (добавление/удаление кастомных тегов, перемещения, ссылки на оригинал, каталогизация и тд)

Но при загрузке изображений в PictureBox RAM стремительно переполняется и вылазит исключение.

Использование GC.Collect, GC.AddMemoryPressure. Не сильно помогло. PicBox.Image.Dispose(); вызывает исключение System.ArgumentException: "Недопустимый параметр."

Нужно каким то образом довести потребление памяти до приемлемого количества, предположу что вся проблема в методе отображения изображений, но ничего лучше я не придумал. И при этом количество изображений превышает 1500 шт.

C#
1
2
3
4
5
6
7
8
        List<PictureBox> pictureBox = new List<PictureBox>();
        PictureBox PicBox;
        private string source_wayPanel = @"";
        private bool FirstImageWindow = true;
        private byte HMaxLocalImageWindow = 0;
        private int x = 0;
        private int y = 0;
        private int k = 0;
...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
try
            {
                DebugBTN.Enabled = false;
                ResultPanel.AutoScroll = false;
                DirectoryInfo FileInfo = new DirectoryInfo(source_wayPanel);
                FileInfo[] Files = FileInfo.GetFiles("*");
                foreach (FileInfo file in Files)
                {
                    try
                    {
                        if (HMaxLocalImageWindow == 7) { y += 105; HMaxLocalImageWindow = 0; x = 0; FirstImageWindow = true; }
                        //создание
                        PicBox = new PictureBox();
                        if (FirstImageWindow) { PicBox.Left = 0; FirstImageWindow = false; HMaxLocalImageWindow++; }
                        else { x += 105; PicBox.Left = x; HMaxLocalImageWindow++; }
                        PicBox.Top = 20 + y;
                        PicBox.Height = 100;
                        PicBox.Width = 100;
                        PicBox.Visible = true;
                        string imageWay = Path.Combine(source_wayPanel, file.Name);
                        PicBox.Image = Image.FromFile(imageWay);
                        PicBox.SizeMode = PictureBoxSizeMode.StretchImage;
                        //размещаем на панели
                        ResultPanel.Controls.Add(PicBox);
                        //добавляем в коллекцию        
                        Image.FromFile(imageWay).Dispose();
 
                        GC.Collect(1, GCCollectionMode.Forced);
                        GC.AddMemoryPressure(1);
                        k++;
                    }
                    catch (Exception ex)
                    {
                        //MessageBox.Show(Convert.ToString(ex.Message));
                    }
                }
                ResultPanel.AutoScroll = true;
                DebugBTN.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(Convert.ToString(ex.Message));
                ResultPanel.AutoScroll = true;
                DebugBTN.Enabled = true;
            }
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.06.2018, 23:30
Ответы с готовыми решениями:

Уменьшение используемого объёма памяти при работе с изображениями
Здравствуйте, вот сейчас я пытаюсь сделать простенькую игру. И вот я столкнулся со след. проблемой при отрисовке карты: Моя карта...

Переполнение оперативной памяти при работе макроса
Добрый всем вечер! Товарищи программисты, подскажите, пожалуйста, идеи по следующей проблеме. Есть макрос, который производит в цикле...

Артефакты при работе с изображениями
Здравствуйте, я занимаюсь обработкой изображений, и столкнулся с проблемой появления посторонних пикселей. Допустим вот пример кода который...

27
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,920
Записей в блоге: 14
21.06.2018, 06:57
Студворк — интернет-сервис помощи студентам
MaikasUA,
Цитата Сообщение от MaikasUA Посмотреть сообщение
Начиная от 259x194 и заканчивая 3000x2800
Вы больше одного 3000*2800 на FullHD экране всё равно не уместите.

Цитата Сообщение от belalugoci Посмотреть сообщение
Хотел предложить такой вариант, если вам нужны только небольшие превью, то или делать кеш как делает винда (привет Thumbs.db) или при загрузке делать мелкую превью и ее добавлять в PicBox, а tempPicBox использовать для следующего файла, тогда у вас размеры уменьшатся.
Именно.
На форме надо отображать уменьшенные изображения.
Уменьшать можно сторонними библиотеками. Возможно, найдётся что-то достаточно быстрое.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
21.06.2018, 07:01
Цитата Сообщение от MaikasUA Посмотреть сообщение
буду пытаться переписать код
я бы наверное делал так - читал картинки в папке, а теперь зная их число X, создавал бы X объектов PicBox на панели, а чтение и рисование превьюшек делал только для активных объектов когда скролл статичен, если скролл крутят, то есть мышка зажата на бегунке, чтобы крутились просто пустые объекты PicBox, а при отпускании или замирании мыши на 1-2 секунды, чтобы прорисовывались. Тогда вы будете манипулировать 30-50 мб памяти.
А если прикрутить модуль для работы с архивами, то превьюшки кешировать внутрь zip файла, назвать его MegaThumbs.db это позволит не занимать кластеры на диске и не напрягать HDD/SSD, сжатие в таком файле можно и отключить.
0
3 / 3 / 3
Регистрация: 24.05.2017
Сообщений: 32
21.06.2018, 07:02  [ТС]
belalugoci,
Цитата Сообщение от belalugoci Посмотреть сообщение
динамическое создание превью при загрузке
Я в принципе представляю себе как сделать, но использование кэша было бы отличной альтернативой на случай если проц слишком слабый. Но как использовать кэш я даже не представляю. Можно пример?
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
21.06.2018, 07:03
Цитата Сообщение от Rius Посмотреть сообщение
Вы больше одно 3000*2800 на FullHD экране всё равно не уместите.
а у него там
C#
1
2
3
                        PicBox.Height = 100;
                        PicBox.Width = 100;
                        PicBox.SizeMode = PictureBoxSizeMode.StretchImage;
поэтому умещается много.
0
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,920
Записей в блоге: 14
21.06.2018, 07:06
Цитата Сообщение от belalugoci Посмотреть сообщение
поэтому умещается много.
Мелкие умещаются. А крупные в исходном виде не выводятся, т.к. даже не поместятся. Поэтому грузить крупные - бессмысленно.
Можно с помощью команд ImageMagick перекодировать кучу исходных изображений в превьюшки.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
21.06.2018, 07:13
Цитата Сообщение от MaikasUA Посмотреть сообщение
Но как использовать кэш я даже не представляю. Можно пример?
Сам не делал, но я бы генерировал какой-то хэш для файла и создавал бы его отображение в папке Cache, то есть например файл
суперкартинкасдевчатами.png
имел бы после получения хэша имя
ghd634gfghd63.png

При обращении к картинке в foreach проверяете FileExists в папке Cache и если находите совпадение, то открываете файл из кеша, если совпадения нет, то открываете оригинал, создаете кеш, превью попадает на панель, а память от оригинала освобождаете. В итоге будете банально даже скроллом пользуясь кешировать папку за один проход.
Формально, если позволяет решаемая задача, вы можете кеш строить до начала работы или наоборот в момент закрытия. В общем любая оптимизация отталкивается от самой задачи. Я в своё время изменив подход к работе с данными с большой базой SQL, оптимизировал код так, что вместо десятков тысяч запросов у меня остался один запрос на чтение и один на изменение, скорость выросла примерно в 100000 раз (до того как нашел решение я даже запускал обработки в несколько потоков и мечтал о процессоре с HyperThreading (как раз вышли первые Pentium 4 с такой фичей)).

Добавлено через 2 минуты
Цитата Сообщение от Rius Посмотреть сообщение
Мелкие умещаются. А крупные в исходном виде не выводятся, т.к. даже не поместятся.
не понял о чем вы. Там же просто сожмется до окна 100х100. Ну не будет понятно что там изначально , но что значит "не поместятся"?
0
Эксперт .NET
 Аватар для Rius
13837 / 7879 / 1706
Регистрация: 25.05.2015
Сообщений: 23,920
Записей в блоге: 14
21.06.2018, 07:23
Цитата Сообщение от belalugoci Посмотреть сообщение
но что значит "не поместятся"?
ТС не выводит изображения в их исходном размере. Они в таком на экран не влезут.
Поэтому контролы PictureBox размером 100*100 . Но файл в память грузится всё равно исходного размера, распаковывается в Bitmap и после уменьшается в разрешении до 100*100 уже самим контролом (PictureBoxSizeMode.StretchImage), чтобы отобразиться в нём.
Отсюда такой расход памяти.

Добавлено через 2 минуты
Цитата Сообщение от belalugoci Посмотреть сообщение
При обращении к картинке в foreach проверяете FileExists в папке Cache и если находите совпадение, то открываете файл из кеша, если совпадения нет, то открываете оригинал, создаете кеш, превью попадает на панель, а память от оригинала освобождаете. В итоге будете банально даже скроллом пользуясь кешировать папку за один проход.
+ Если файла нет, из пула берётся поток, запускающий создание файла превью. И после его отработки в программу сообщается о появлении файла превью, и он загружается туда, куда должен был попасть сразу при наличии файла.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
21.06.2018, 07:25
Цитата Сообщение от Rius Посмотреть сообщение
Отсюда такой расход памяти.
Это было понятно изначально, я не понял контекст ваших слов.
Мелкие умещаются. А крупные в исходном виде не выводятся, т.к. даже не поместятся. Поэтому грузить крупные - бессмысленно.
Видимо вы про оперативку. А я про экран. Так как до этого вы говорите именно про экран:
Вы больше одного 3000*2800 на FullHD экране всё равно не уместите.
Добавлено через 1 минуту
Цитата Сообщение от Rius Посмотреть сообщение
+
Почему "+", если я уже написал про это?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.06.2018, 07:25

При работе с 24-разрядными изображениями происходят искажения
пытаюсь заставить этот код работать, для начала просто открываю бмп файл, и сохраняю данные в другой бмп файл, так вот с 16,256-цветными...

Ошибка доступа при работе с изображениями в DrawGrid
//при нажатии на кнопку в 1 ячейке 1 столбце должно появляться изображение, но выдает ошибку доступа к файлу void __fastcall...

Переполнение стека при работе с матрицей
Доброго времени суток. У меня такой вопрос: у меня есть матрица 1000x1000 тип float компиллятор на эту матрицу не ругается, но во время...

Помогите разобраться с ошибкой при работе с изображениями, пожалуйста
Когда делал сайт под CMS MODx столкнулся с тем, что нужно было сделать галерею фотографий на сайте. В результате довольно долгого...

Ошибка при работе с изображениями: The name 'ResolveUrl' does not exist in the current context
Здравствуйте! Нашел пример как работать с изображениями, но выходит ошибка. Пример: http://msdn.microsoft.com/en-us/library/aa479350.aspx...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru