Форум программистов, компьютерный форум, киберфорум
C++/CLI Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 25.07.2012
Сообщений: 41

Очень медленной прорисование картинки. Как ускорить?

31.07.2012, 21:23. Показов 2498. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Требуется вывести матрицу в графическом варианте. Т.е. заполнить картинку точками различной яркости/призрачности (не так важно) в зависимости от значений матрицы.
Попробовал при помощи битмапа и сетпикселя. Но оочень медленно. Подскажите, правильно ли вообще я делаю, как можно ускорить выполнение подобной операции. Логично ли для этого переходить к использованию специальных библиотек для графики (директ икс??), с которыми я ранее и не пытался работать.
К тому же, мне можно выводить прозрачность с градацией меньшей, чем 256, но как это сделать, я не понял.
C++
1
2
3
4
5
6
7
8
9
10
11
 Bitmap^ myBitmap = gcnew Bitmap(1,1);
 System::Drawing::Graphics^ myGr = this->pictureBox1->CreateGraphics();
     for (int j=0; j<pictureBox1->Width; j++)
     {
        for (int i=0; i<pictureBox1->Height; i++)
        {                    
            int myBright = safe_cast<int>((matrix->GetElement((i*matrix->GetTimeDimension()/pictureBox1->Height), j*matrix->GetAngleDimension()/pictureBox1->Width)-matrix->GetMin())/(matrix->GetMax()-matrix->GetMin())*255);
            myBitmap->SetPixel(0,0, Color::FromArgb(myBright,Color::Black));
            myGr->DrawImage(myBitmap,Point(j,i));
        }
    }
Заранее спасибо за все подсказки.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.07.2012, 21:23
Ответы с готовыми решениями:

Очень медленно скачивает страницу (TIdHTTP). Как ускорить?
Скачивает страницу с любого сайта за 2-4 секунды. При этом браузер (Google Chrome) за полсекунды-полторы секунды отрабатывает. Из-за...

Добавляю из ресурсов картинки. Их много. Как ускорить процесс?
int y = 0; Image iArr = new Image; for (int i = 1; i &lt;= iArr.Length; i++, y++) { ...

Как сделать эту программы ввод/вывод через sys.stdin? Хочу ускорить. В C++ это очень хорошо ускоряет?
h = {} i = 0 for _ in range(int(input())): # считывает количества списков s = input() # удаляет первое число в строке s =...

9
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
01.08.2012, 02:11
hamster28, напишите что представляет из себя matrix ?
что записано в matrix ?
И что это за формула ?
C++
1
 int myBright = safe_cast<int>((matrix->GetElement((i*matrix->GetTimeDimension()/pictureBox1->Height), j*matrix->GetAngleDimension()/pictureBox1->Width)-matrix->GetMin())/(matrix->GetMax()-matrix->GetMin())*255)
Для яркости есть
GetBrightness() - зная цвет получим яркость .
0
0 / 0 / 0
Регистрация: 25.07.2012
Сообщений: 41
01.08.2012, 09:29  [ТС]
1 - matrix - матрица даблов размерностью примерно 4000*70
2 - фактически это (элемент матрицы - минимум)/(максимум-минимум) - отношение от нуля до единицы, которое домножаем на 255 и округляем, чтоб было значение яркости или прозрачности точки
3 - GetBrightness() - это яркость пикселя, если я правильно понял. уже существующего. а мне нужно просто из обычной числовой матрицы придумать зависимость расставления яркостей по полю картинки.

Добавлено через 1 час 37 минут
Вот, переписал для понятности. Сейчас matrix это массив целочисленных элементов со значениями от 0 до 255. При размерах picturebox1 приблизительно 400 на 300 пикселов время вывода на экран около полутора минут. Хотелось бы ускорить выполнение операции.
C++
1
2
3
4
5
6
7
8
9
10
11
Bitmap^ myBitmap = gcnew Bitmap(1,1);
 System::Drawing::Graphics^ myGr = this->pictureBox1->CreateGraphics();
     for (int j=0; j<pictureBox1->Width; j++)
     {
        for (int i=0; i<pictureBox1->Height; i++)
        {                    
            int myBright = matrix[j][i];
            myBitmap->SetPixel(0,0, Color::FromArgb(myBright, Color::Black));
            myGr->DrawImage(myBitmap,Point(j,i));
        }
    }
0
1617 / 1182 / 553
Регистрация: 08.01.2012
Сообщений: 4,560
01.08.2012, 11:01
hamster28, GetPixel,Set/PutPixel - самый медленный вариант работы с графикой, надо непосредственно работать с памятью, помогает ассемблер
0
0 / 0 / 0
Регистрация: 25.07.2012
Сообщений: 41
01.08.2012, 13:19  [ТС]
MansMI, спасибо за идею, а можешь привести пример.
И какие есть еще варианты работы с графикой кроме Pixel и ассемблера?
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
01.08.2012, 23:06
hamster28, вот хороший пример http://msdn.microsoft.com/ru-r... 6(v=vs.90)

Переделал этот пример. Вам остается исправить код под свой массив

Коротко опишу решение:
Создаем массив по размеру pictureBox-а и заполняем значениями 0 - 255.
Этот массив для прозрачности .
Дальше используя массив создаем
черно - белое изображение из точек ( прямоугольников размером в 1 пиксел )
Задаем цвет кажд. точке ( черн.цвет и прозрачность ).

По нажатию кнопки - происходит отрисовка ( очень быстро )


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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    private:
 
        Bitmap^ CreateBitmap( int width, int height )
{
 
    // СОЗДАЕМ МАССИВ  ПО РАЗМЕРУ pictureBox 
    //////////////////////////////////////////////////////////////////
 
            const    long int ROW = pictureBox1->Width;
            const    long int COL = pictureBox1->Height;
 
                     long int     i, j;
 
                array < double, 2 > ^arr = gcnew array < double, 2 > ( ROW + 1, COL + 1 ) ;
 
         
 
                 Random^ myrnd = gcnew Random();
 
                  for ( i = 0; i < ROW ; i++)
     
                      for ( j = 0; j < COL ; j++)
 
                arr[ i, j ] =  myrnd->Next( 255 ); 
 
    ////////////////////////////////////////////////////////////////////////
 
 
                  Bitmap^ bmp = gcnew Bitmap(width, height);
 
                   Graphics^ g = Graphics::FromImage(bmp);
 
 
 
Pen ^pen = gcnew Pen( Color::Black );
 
        for ( i = 0; i < ROW - 1 ; i++)
        for (  j = 0; j < COL - 1; j++)
        {         
    
            pen->Color = Color::FromArgb( arr[ i, j ] ,  Color::Black );
            g->DrawRectangle( pen, Rectangle(( float)i, ( float)j, 1.0, 1.0) );
           
        }
    
    return bmp;
}
 
 
 
 
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
 
 
 
                 System::Drawing::Graphics^ myGr = this->pictureBox1->CreateGraphics();
 
                  Bitmap^ bmp = CreateBitmap( pictureBox1->Width,  pictureBox1->Height );
                  myGr->DrawImage(bmp, 0, 0);
}
1
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
03.08.2012, 06:28
.....................

Добавлено через 8 минут
небольшие неточности
cтр. 15
C++
1
 array < double, 2 > ^arr = gcnew array < double, 2 > ( ROW + 1, COL + 1 )
нужно
C++
1
 array < int, 2 > ^arr = gcnew array < int, 2 > ( ROW , COL )
стр.38-39
C++
1
2
 for ( i = 0; i < ROW - 1 ; i++)
        for (  j = 0; j < COL - 1; j++)
нужно
C++
1
2
 for ( i = 0; i < ROW  ; i++)
        for (  j = 0; j < COL ; j++)
В для своего примера сгенерировал массив .
У вас hamster28 массив уже есть
Цитата Сообщение от hamster28 Посмотреть сообщение
Сейчас matrix это массив целочисленных элементов со значениями от 0 до 255
0
0 / 0 / 0
Регистрация: 25.07.2012
Сообщений: 41
03.08.2012, 19:35  [ТС]
MrCold
да, да. сообразил. большое спасибо. выводится быстро.

еще вопрос, на будущее - как быстрее всего перерисовывать эту матрицу, если в ней будет меняться 1 столбец каждые n времени. Перерисовать полностью? или есть варианты с перерисовкой 1 столбца, 1 сектора картинки?
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
04.08.2012, 15:41
Добавлено через 17 минут
Цитата Сообщение от hamster28 Посмотреть сообщение
как быстрее всего перерисовывать эту матрицу
Скорость отрисовки зависит от размера битмапа .
Тем более лепим изображение из отдельных пикселей .

Проверим .
Добавим второй битмап
( размер 1/4 первого) и измерим скорость для каждого
Результат выведем в MessageBox
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
//////                             #include <ctime>
 
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
 
                 
                clock_t a, b, c, d;
 
                 System::Drawing::Graphics^ myGr = this->pictureBox1->CreateGraphics();
 
                 a = clock();
 
                  Bitmap^ bmp = CreateBitmap( pictureBox1->Width,  pictureBox1->Height );
 
                  myGr->DrawImage( bmp, 0, 0 );
 
                  b = clock();
 
 
                   c = clock();
 
                  Bitmap^ bmp2 = CreateBitmap( pictureBox1->Width/4,  pictureBox1->Height );
 
                  myGr->DrawImage( bmp2, 0, 0 );
 
                  d = clock();
 
                  MessageBox::Show( this, "First Image " + ( ( double )( b - a )/CLOCKS_PER_SEC ).ToString() + ",    Second Image  " + ( ( double )( d - c )/CLOCKS_PER_SEC ).ToString() );
 
                // }
Перерисовать сектор будет быстрее . Проблема ни в этом . Можно, было бы,
рисовать новый сектор поверх старого , Но здесь используется прозрачность.
Поэтому сектор придется затирать цветом фона.
Быстрая затирка, а вывод картинки медленный . Результат
получаем - пустой участок.
Как перерисовать
а потом затереть, потом опять перерисовать, да так что не наблюдать пустого участка ?
??????? Тут затрудняюсь с ответом .
Если не использовать прозрачность то проблемы нет - Достаточно рисовать новый сектор
на месте старого .

Формируем цвет не используя прозрачность
C++
1
2
3
4
5
6
7
8
9
10
 
 for ( i = 0; i < ROW; i++)
        for (  j = 0; j < COL; j++)
        {         
    
            pen->Color = Color::FromArgb( arr[ i, j ] ,  arr[ i, j ], arr[ i, j ] );
            g->DrawRectangle( pen, Rectangle( ( float)i, ( float)j, 1.0, 1.0) );
             
           
        }
где значения R, G, B ( красный, зеленый, синий ) берем из массива
Получаем черно-белое изображение .

Дальше нам нужно один раз вывести основное изображение на PictureBox

Цитата Сообщение от hamster28 Посмотреть сообщение
еще вопрос, на будущее - как быстрее всего перерисовывать эту матрицу, если в ней будет меняться 1 столбец каждые n времени. Перерисовать полностью? или есть варианты с перерисовкой 1 столбца, 1 сектора картинки?
И затем перерисовывать не нужно теперь достаточно выводить 1 сектор
поверх картинки .

( Проверил через таймер - все замечательно выводится , смена едва заметна ) .
1
0 / 0 / 0
Регистрация: 25.07.2012
Сообщений: 41
05.08.2012, 02:42  [ТС]
Огромное спасибо за полный ответ. Очень помог.
Если еще возникнут вопросы - буду писать, а пока все ясно, еще раз спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.08.2012, 02:42
Помогаю со студенческими работами здесь

Как бороться с медленной загрузкой файлов в LiteDB?
Всем привет! Недавно начал работать с файловой БД LiteDB, пока что все устраивает, но есть одно НО =( загружал файл .mp4 длительностью...

Смена Картинки(очень нужно)
Привет друзья . сразу прошу прощения за свой русский так как очень довно не живу в русско говорящей стране. проблема такова... ...

Взаимодействие МК с "медленной" периферией
Добрый день. Есть МК (STM32) и есть датчик. Датчик этот, после запроса от МК, выполняет команду некоторое количество времени, например...

В чём причина медленной работы компьютера?
Комп медленно работает. Хотелось бы найти причины. Поделал отчётов в AIDA64, CrystalDiskInfo, smartmontools (эти не приложил, т.к....

Найти причину медленной работы скрипта
на тестовом мини-сайте http://dashenyka.esy.es/ на странице форума тупит скрипт. В чём может быть причина. В основном всё работает норм....


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru