Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62

Доступ к bitmap и элементам формы из другого потока. Вычисление площади произвольной фигуры

16.02.2016, 16:31. Показов 2034. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Делаю программу для демонстрации вычисления площади произвольной фигуры различными методами (Монте-Карло, перебор и др.). Фигура создаётся из координат мыши в событиях MouseDown/Move/Up и сохраняется в List в виде точек, который потом отображается на bitmap как полигон.
В основном потоке из события OnPaint идёт доступ к двум bitmap'ам (фигура и маска для отображения работы методов)
C#
1
2
e.Graphics.DrawImage(bitmap, 0, 0);
e.Graphics.DrawImage(mask, 0, 0);
При нажатии на кнопку вычисления площади, запускается фоновый поток, который для метода Монте-Карло, например, задаёт рандомные x и y, смотрит bitmap.GetPixel(x,y) и в mask выводит в этой точке пиксель с нужным цветом с помощью mask.SetPixel(x, y, Color.FromArgb(0, 200, 0));, также по завершении поток выводит информацию в textbox на форме. Естественно, при этом вылазит ошибка доступа из параллельного потока для элементов и для bitmap, если в момент вычисления произойдёт перерисовка.
Как можно это грамотно реализовать, чтоб при этом не умирал интерфейс во время вычислений? И ещё, Get и Set Pixel достаточно быстро работают, чтоб использовать их в таком ключе?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.02.2016, 16:31
Ответы с готовыми решениями:

Доступ к элементам формы из другого потока
Хочу сделать в фоновом потоке добавление UserControl в StackPanel. Старт потока: Thread t = new Thread(Add); ...

Доступ к элементам формы из другого потока
Есть функция, которая запускается отдельным потоком: static unsigned __clrcall ThreadFunc1(void* pArguments) { Form1 ^...

Доступ к элементам формы из другого потока
В общем, у меня есть много разных функций, которые вызывают другие функции, в которых происходят разные операции типа копирования файлов,...

6
 Аватар для bodynar
345 / 307 / 135
Регистрация: 14.03.2015
Сообщений: 1,158
Записей в блоге: 1
16.02.2016, 17:19
Пункт 3
0
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62
16.02.2016, 18:23  [ТС]
Цитата Сообщение от bodynar Посмотреть сообщение
Пункт 3
Но это не решит проблему параллельного доступа к bitmap
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
16.02.2016, 19:15
Цитата Сообщение от sereja322 Посмотреть сообщение
И ещё, Get и Set Pixel достаточно быстро работают, чтоб использовать их в таком ключе?
Это крайне медленные методы. Используйте какой-нибудь из выложенных классов для более никоуровневой работы с битмапом, например этот. Скорость отличается во много раз.

На счет проблемы с доступом-а зачем вы вообще перерисовываете на экране битмап, в котором что-то делает другой поток? Подождите сначала, пока доделает, а потом уже отображайте. А для доступа к контролам из других потоков есть Invoke/BeginInvoke.
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
16.02.2016, 19:28
sereja322, Вам не нужно ни создавать Bitmap, ни обращаться к нему.
Вместо этого используйте GraphicsPath.
GraphicsPath может использоваться как для прорисовки, так и для математических вычислений.
Находится ли точка внутри фигуры можно определить методом IsVisible.
0
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62
16.02.2016, 20:49  [ТС]
Цитата Сообщение от EvilFromHell Посмотреть сообщение
На счет проблемы с доступом-а зачем вы вообще перерисовываете на экране битмап, в котором что-то делает другой поток?
Я хочу, чтоб результат был виден в реальном времени, допустим у нас bitmap 100x100 и процессор обрабатывает 1 пиксель в миллисекунду, т.е. весь процесс займёт 10 секунд, а в основном потоке в это время вызывается 30 раз в секунду timer, который отображает bitmap, а поверх него mask с зарисованными пикселями.

Добавлено через 1 час 17 минут
Цитата Сообщение от Storm23 Посмотреть сообщение
sereja322, Вам не нужно ни создавать Bitmap, ни обращаться к нему.
Вместо этого используйте GraphicsPath.
GraphicsPath может использоваться как для прорисовки, так и для математических вычислений.
Находится ли точка внутри фигуры можно определить методом IsVisible.
Вот такой код:
C#
1
2
3
4
5
6
7
8
9
10
11
width = figure.GetBounds().Width;// bitmap.Width;
height = figure.GetBounds().Height;
 
for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
        if (figure.IsVisible(x, y))
            sqrt++;
    }
}
вычисляется 11 секунд, а такой:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
width = bitmap.Width;// figure.GetBounds().Width;// bitmap.Width;
height = bitmap.Height;// figure.GetBounds().Height;
 
for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
        pixel = bitmap.GetPixel(x, y);
 
        if (pixel.R != 0 || pixel.G != 0 || pixel.B != 0)
            sqrt++;
    }
}
242 миллисекунды. Похоже я что-то делаю не так...
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
17.02.2016, 05:31
Цитата Сообщение от sereja322 Посмотреть сообщение
Похоже я что-то делаю не так...
Нет, все так. Конечно GrphicsPath будет медленнее, ведь он вычисляет нахождение каждой точки внутри себя. А битмап берет уже готовое. С другой стороны, в GraphicsPath можно посчитать площадь с любой точностью, в то время как точность битмапа ограничена его разрешением.
К тому же, вычислять монте-карло на битмапе - не рационально. Ведь в битмапе можно просто посчитать число всех заполненных точек - и получим площадь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.02.2016, 05:31
Помогаю со студенческими работами здесь

Доступ к элементам формы из другого класса/Потока
Здравствуйте, у меня есть класс работы потоков, при выполнении метода (В потоке) должна идти запись в label на форму, подскажите как это...

Обращение к элементам формы с другого потока
Есть форма, есть потоки, которые должны получить доступ к ProgressBar'у, расположенному на форме. Делал так: module *** Private...

Обращение к элементам формы из другого потока
Короче говоря многопоточность это моя слабость. Сколько статей перечитал уже, один хрен не пойму как они синхронизируются и как...

Обращение к элементам формы из другого потока
Извиняйте за очередную тему. Тут на форуме я уже их много прочитал, но все равно не могу понять эти делегаты и инвок. На форуме есть...

Доступ к элементам формы из потока
Доброго дня! Создал поток через CreateThread (...,mythread,...) Подскажите, как получить из потока доступ к компонентам Формы класса?


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru