Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.140.185.123] |
|
Сообщ.
#1
,
|
|
|
Все работает, но функция StretchBlt выполняется 2.5 миллисекунды, а надо не более 1 миллисекунды. Пробовал в памяти делать StretchBlt, а потом BitBlt в окно. Но оказалось, что BitBlt берет дополнительно 1 миллисекунду!
Может кто работал с такой задачей? Изучал работу с GDI+, но оказалось, что в таком варианте отрисовка битмапа занимает еще больше времени. |
Сообщ.
#2
,
|
|
|
Накидай тестовый пример, плс.
|
Сообщ.
#3
,
|
|
|
В каком режиме выполняется StretchBlt? (формат картинки, цвета, увеличение/уменьшение, SetStretchBltMode ?)
Например, для обработки 32-битного изображения форматом 1024x1024 => 1500x1500 со временем 1 мс. требуется пропускная способность памяти 12 гигабайт в секунду. |
Сообщ.
#4
,
|
|
|
Цитата MBo @ В каком режиме выполняется StretchBlt? (формат картинки, цвета, увеличение/уменьшение, SetStretchBltMode ?) Например, для обработки 32-битного изображения форматом 1024x1024 => 1500x1500 со временем 1 мс. требуется пропускная способность памяти 12 гигабайт в секунду. Про режимы я не знаю, никогда не использовал. Функция такая: Pdc.StretchBlt(0, 0, Cr.right-Cr.left, Cr.bottom-Cr.top,&dc, 0,0,ICON_32*M10,ICON_32*(N10+1),SRCCOPY); Сначала я подготавливаю картинку в памяти в dc, а потом сжимаю в окно на экране. Это окно может изменять размеры, и тогда соответственно меняется CRect Cr. dc - это контекст в памяти, Pdc - экранный контекст. Причем отрисовка в памяти выполняется за 200 - 300 микросекунд, а StretchBlt аж за 2.5 миллисекунды. У меня большой проект, я завтра накидаю демо и выложу на форуме. Большое спасибо за внимание к моему вопросу. Может действительно надо какой то режим установить? При создании битмапа я не указываю цветность, она как то берется по умолчанию: if (IsBitmap == false) { if (bm != NULL) delete bm; bm = NULL; bm = new CBitmap; bm->CreateCompatibleBitmap(&Pdc, 32 * M10, 32 * (N10 + 1)); IsBitmap = true; IsPaint = false; }; |
Сообщ.
#5
,
|
|
|
Вот написал демку. В ней в Paint создается битмап 1500х1500 и сжимается в контекст на экране. Сначала был битмап из ресурса 48х48,
так выводился за 150 микросекунд, а когда я стал выводить битмап 1500х1500, время увеличилось и стало почти 16 миллисекунд. В моем проекте битмап такого же размера. Видимо время зависит от исходного размера. Может есть другой способ вывода? Прилагаю проект. Файл с протоколом времени отрисовки FileProfOtladki_ms.txt Прикреплённый файлDemo.rar (133,08 Кбайт, скачиваний: 109) |
Сообщ.
#6
,
|
|
|
Цитата a_n_y_a @ Вот написал демку. Сразу вызывает вопросы. В методе "void CDemoW::OnPaint()" многократно выполняются одни и те же действия по созданию/инициализации одних и тех же объектов с одинаковыми параметрами. Что только бессмысленно тратит время. Эти действия просятся в другое место программы. Добавлено Цитата a_n_y_a @ Сначала я подготавливаю картинку в памяти в dc, а потом сжимаю в окно на экране. Это окно может изменять размеры, и тогда соответственно меняется CRect Cr. dc - это контекст в памяти, Pdc - экранный контекст. Причем отрисовка в памяти выполняется за 200 - 300 микросекунд, а StretchBlt аж за 2.5 миллисекунды. Сразу возникает идея - поскольку рисовать быстрее, чем потом масштабировать, давайте попытаемся написать алгоритм общего вида. Который будет сразу рисовать картину правильно в зависимости от размеров окна. И, таким образом, при изменении размеров окна картина будет не масштабироваться, а перерисовываться целиком. |
Сообщ.
#7
,
|
|
|
Цитата ЫукпШ @ Сразу возникает идея - поскольку рисовать быстрее, чем потом масштабировать, давайте попытаемся написать алгоритм общего вида. Который будет сразу рисовать картину правильно в зависимости от размеров окна. И, таким образом, при изменении размеров окна картина будет не масштабироваться, а перерисовываться целиком. Это в демке так происходит отрисовка. В целевом проекте создается картинка один раз, и при каждой отрисовке перерисовываются только те участки, которые изменились. Для поля 45х30 таких участков не более 10. В демке, которую я выложил показана только отрисовка большого битмапа на экран. Если вы смотрели функцию Paint, в ней замеряется время только функции StretchBlt: double tt = pt.GetMsCurrentTime(); Pdc.StretchBlt(0, 0, Cr.right - Cr.left, Cr.bottom - Cr.top, &dc, 0, 0, 1500, 1500, SRCCOPY); tt = pt.GetMsCurrentTime() - tt; Создание картинки не учитывается во времени отрисовки. Но если создавать битмап сразу по размеру окна на экране, то потом надо будет работать с функцией BitBlt, по моему опыту, если StretchBlt выполняется за 2.5 миллисекунды, то BitBlt за 1 миллисекунду. Это хорошо, но сегодняшние измерения времени отрисовки на разных компьютерах показали, что на слабых компьютерах время отрисовки может увеличиться в 4-10 раз! Вероятно задача не имеет общего решения и надо оговаривать минимальные требования к компьютеру, на котором будет работать моя целевая программа. |
Сообщ.
#8
,
|
|
|
Цитата a_n_y_a @ ... но сегодняшние измерения времени отрисовки на разных компьютерах показали, что на слабых компьютерах время отрисовки может увеличиться в 4-10 раз! А это что, так критично ? Если требуемое число картинок в единицу времени (в среднем) меньше, чем время отрисовки одной, то совершенно всё равно, сколько времени тратится на рисование. Хоть 10 секунд. Надо только отделить мероприятие по рисованию от мероприятий по выводу. Событие "OnPaint" используем для вывода картинки. Поскольку требуется 1 [мс] всё получится отлично. А рисуем в другом потоке. И там же решаем проблемы масштабирования. --- Даже если найдётся очень слабый старый комп, алгоритмически можно элементарно решить проблему. Будем рисовать и выводить столько, сколько сможем. Если сможем не всё - будем пропускать отдельные картинки. Подобные неприятности могут случится и на новом сверх-мощном компьютере. В том случае, если он окажется в какой-то момент времени до предела загружен. Это значит, что "рекомендации и требования к компьютеру" не самый лучший выход. |