Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.09.2015, 19:56   #1
ashtone9130
Пользователь
 
Регистрация: 17.01.2010
Сообщений: 45
По умолчанию Как ускорить процесс зарисовки изображения из матрицы

Суть проблемы вот в чем. Имею двухмерную матрицу чисел 512х512, числа в матрице в пределах от 800 и до 2500. Далее приравняв максимальное число к белому цвету а минимальное к черному, остальные рассчитываю относительно первых, надо вывести эту матрицу на экран, путем зарисовки пикселей (512х512) соответствующим цветом (от белого к черному). В итоге получится некая серая рябь. Но проблема в том, что зарисовка происходит уж очень медленно, видно как кадр построчно рисуется. Как ускорить данный процесс?? или хотя бы как сделать так, что бы не было видно самого процесса зарисовки, а записать массив цветов каждого пикселя и сразу все вывести разом.

Вот сама функция вывода на экран изображения (переменные min и max глобальные и рассчитываются в другой функции, рисую на Picture Control, к которой привязана переменная m_paint:

Код:
void CMy01Dlg::Kadr()
{
        int amount = (max - min)/32;
        int color;
 
        CDC *pDC = m_paint.GetDC();
        RECT rc;
        m_paint.GetClientRect(&rc);
 
        for ( int i=0; i < 512; i++){
        for( int j=0; j < 512razmer_file_y-1; j++){
           color =255- (((max - mass[j][i])/amount)*8); 
              pDC->SetPixel(i,j,RGB(color,color,color));
 
          }
        }
   m_paint.ReleaseDC(pDC);
}
Я так понял надо копать в сторону SetDIBits и BitBlt, но пока не могу понять как реализовать используя эти функции (Использую Visual Studio 2010 MFC)
ashtone9130 вне форума Ответить с цитированием
Старый 18.09.2015, 20:26   #2
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Код:
onPaint
и будет счастье.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 18.09.2015, 20:47   #3
ashtone9130
Пользователь
 
Регистрация: 17.01.2010
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Smitt&Wesson Посмотреть сообщение
Код:
onPaint
и будет счастье.
это вообще к чему??? насколько знаю onPaint отвечает за прорисовку, или я не прав??... у меня все рисуется, путем вызова этой функции после открытия файла и записи из него данных в массив.. Насколько я понимаю процесс затормаживается из-за постоянного вызова функции SetPixel, которая работает не столь быстро... а вот как её обойти я не знаю
ashtone9130 вне форума Ответить с цитированием
Старый 18.09.2015, 20:48   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Скорее вам надо SetDIBitsToDevice...
Само главное заполнить BITMAPINFO структуру, которая описывает ваши данные.

А, вам надо сделать массив 512х512 из color элементов, поскольку во время рисования считать уже не получится, надо подсчитывать все заранее.
waleri вне форума Ответить с цитированием
Старый 18.09.2015, 20:51   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Я так понял надо копать в сторону SetDIBits
Логично. Вот посмотри тут:
http://www.programmersforum.ru/showthread.php?t=155809
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.09.2015, 21:49   #6
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

И еще не надо всё сразу на конечный контекст пихать, нарисуйте сначала на подопытном контексте, а уж потом выводите.
Croessmah вне форума Ответить с цитированием
Старый 18.09.2015, 22:30   #7
ashtone9130
Пользователь
 
Регистрация: 17.01.2010
Сообщений: 45
По умолчанию

Все решил проблему.

решил подобным образом:

Код:
void CMy01Dlg::Kadr()
{
   CDC *pDC = m_paint.GetDC();
    RECT rc;
    m_paint.GetClientRect(&rc);
    int CX = 512, CY = 512;
    DWORD *lpbInit = new DWORD[CX * CY];

      for (int i = 0; i < CY; i++){
            for (int j = 0; j < CX; j++){
               BYTE color = (BYTE)(255 - ((max - mass[i][j])/raznost)*8);
               lpbInit[i*CX+j] = RGB(color, color, color);
                 }
           }

      BITMAPINFO bmi = {
      sizeof(BITMAPINFOHEADER), CX, CY, 1, 32, BI_RGB, 0,
      0, 0, 0, 0 
      };

      HBITMAP hBitmap = ::CreateDIBitmap(
      pDC->GetSafeHdc(), &bmi.bmiHeader, CBM_INIT,lpbInit, &bmi,          DIB_RGB_COLORS);
     CBitmap bitmap;
     bitmap.Attach(hBitmap);

     pDC->DrawState(CPoint(10, 10), CSize(CX, CY), &bitmap, DST_BITMAP);
     
     bitmap.DeleteObject();
     delete lpbInit;
}
Все рисуется достаточно быстро и незаметно.

Но возникла некая проблемка. Как задать размер пикселя, при прорисовки изображения?? так как рисунок не влазит в отведенную область, да и придется еще работать с более крупными изображениями... вот что бы их масштабировать надо указать размер рисуемого пикселя.. только вот где..

Последний раз редактировалось ashtone9130; 18.09.2015 в 23:20.
ashtone9130 вне форума Ответить с цитированием
Старый 18.09.2015, 23:47   #8
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Все рисуется достаточно быстро и незаметно.
Попробуйте на более слабом ПК

Цитата:
Но возникла некая проблемка. Как задать размер пикселя, при прорисовки изображения?
Фактически изменить разрешение монитора? Нафига оно нужно?
Рисуйте с учетом масштаба.
Как вариант, рисуете всё на подопытном контексте, а потом применяете функцию StretchBlt
Так по сути, сразу и масштабирование и двойная буферизация.

Цитата:
Все рисуется достаточно быстро и незаметно.
Попробуйте на более слабом ПК

Цитата:
Но возникла некая проблемка. Как задать размер пикселя, при прорисовки изображения?
Фактически изменить разрешение манитора? Нафига оно нужно?
Рисуйте с учетом масштаба.
Как вариант, рисуете всё на подопытном контексте, а потом применяете функцию StretchBlt
Так по сути, сразу и масштабирование и двойная буферизация.

Последний раз редактировалось Stilet; 19.09.2015 в 09:19.
Croessmah вне форума Ответить с цитированием
Старый 18.09.2015, 23:54   #9
ashtone9130
Пользователь
 
Регистрация: 17.01.2010
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
Фактически изменить разрешение манитора? Нафига оно нужно?
Рисуйте с учетом масштаба.
Как вариант, рисуете всё на подопытном контексте, а потом применяете функцию StretchBlt
Так по сути, сразу и масштабирование и двойная буферизация.
Не разрешение монитора.. а разрешение картинки... то есть у меня имеется область Paint Control с фиксированным размером 800х512, в таком контроле с легкостью поместится изображение 512х512, а вот 1800х512 уже не влазит, соответственно надо масштабировать изображение, уменьшив его в два раза.. Как то так.

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

Цитата:
Сообщение от Croessmah Посмотреть сообщение
Попробуйте на более слабом ПК

Как вариант, рисуете всё на подопытном контексте, а потом применяете функцию StretchBlt
Так по сути, сразу и масштабирование и двойная буферизация.
Что то я не втыкаю как это реализовать... в роли подопытного контекста играет второй Paint Control??, на который все выводится, потом получается из него изображение масштабируется и он впоследствии чего удаляется, а остается на форме уже второй контрол с нужными размерами изображения или как??

и не могу понять как применить StretchBlt.. так что бы на экран выводить уже готовое изображение

Последний раз редактировалось Stilet; 19.09.2015 в 09:19.
ashtone9130 вне форума Ответить с цитированием
Старый 19.09.2015, 09:39   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

На висте и далее, при включенном Aero буферизация делается автоматически.

А зачем вам вообще создавать BITMAP, тем более DI типа?
На ваш случай есть StretchDIBits
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как ускорить процесс расстановки checkbox Sprat PHP 1 07.04.2012 20:26
Ускорить процесс выгрузки из БД Jl6owa БД в Delphi 8 29.03.2012 02:13
Ускорить процесс Victor1963 Помощь студентам 0 15.11.2011 12:06
Ускорить процесс. Victor1963 Общие вопросы Delphi 3 23.06.2011 21:51
Как ускорить попиксельную обработку изображения Дамир Общие вопросы .NET 1 02.11.2009 12:40