Форум программистов, компьютерный форум, киберфорум
Lazarus
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/18: Рейтинг темы: голосов - 18, средняя оценка - 4.50
 Аватар для CrazyDron
9 / 7 / 4
Регистрация: 08.07.2015
Сообщений: 56

Быстрая отрисовка произвольного изображения

09.04.2017, 19:09. Показов 4259. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.

Ищу способ быстрой отрисовки изображения из буфера (например, массив [1..X,1..Y] оf TColor).

Рисование по канве Canvas.Pixels [X,Y] := {цвет такой-то} работает, но, само собой, крайне медленно.

Немного погуглил про GDI и DirectDraw. Несмотря на их быстрые блиты и смену буфера - опять же, непонятно, как этот буфер готовить. Почти во всех примерах используется объект TBitMap, загружаемый из внешнего файла/стрима и т.д.

В объекте TBitMap не нашёл возможности произвольной смены цвета отдельного пикселя.

Ещё раз немного другими словами:
Я формирую в некоем буфере собственную текстуру. Предпочтительно TColor, но можно использовать и другой формат.
Затем мне этот бэкбуфер нужно вывести на экран. На форму, в TImage - особо неважно, куда именно.

Вопрос исключительно в скорости вывода.

Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.04.2017, 19:09
Ответы с готовыми решениями:

Быстрая отрисовка 2D
Приветствую всех! Быть может кто либо знает и может подсказать библиотеку для быстрой отрисовки 2d в vb net? Загвоска в том, что нужно...

Отрисовка изображения поверх канвы (изображения) и вращение изображения
Здравствуйте. Столкнулся с 2умя проблемами при работе с изображениями средствами C++ Builder. Хочу сделать одну интересную штуку, но...

Быстрая отрисовка по текстуре
Всем хорошего дня! Не сумел найти более быстрый способ для рисования по текстуре, помимо SetPixel. Texture2D texture = new Texture2D(127,...

9
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
10.04.2017, 03:41
TColor это тот же Integer. Зачем вам "свой массив", когда можно создавать DIB-секцию, которая по сути уже массив с неким заголовком?

Добавлено через 2 минуты
Лазарус... то есть вам кроссплатформенность нада? Тогда подождём профильных специалистов, знающих как кроссплатформенно создавать DIB.
1
 Аватар для CrazyDron
9 / 7 / 4
Регистрация: 08.07.2015
Сообщений: 56
10.04.2017, 08:55  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
TColor это тот же Integer. Зачем вам "свой массив", когда можно создавать DIB-секцию, которая по сути уже массив с неким заголовком?
По типу - знаю. Вот за DIB-массив хотелось бы узнать поподробнее.

Цитата Сообщение от GoodWeather Посмотреть сообщение
Лазарус... то есть вам кроссплатформенность нада?
Нада. В частности, WinCE. А там нет ни DirectDraw, ни тем более OpenGL'а. Да и GDI, подозреваю, что достаточно кастрированный...
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
10.04.2017, 20:17
https://en.wikipedia.org/wiki/... _in_memory
1
 Аватар для CrazyDron
9 / 7 / 4
Регистрация: 08.07.2015
Сообщений: 56
04.05.2017, 13:25  [ТС]
Поднимаю тему.

Загружаю bmp:
hBMP:=LoadImage(0,'1.bmp',IMAGE_BITMAP,0 ,0,LR_LOADFROMFILE);
Отрисовываю BitBlt'ом - работает.
Создаю свой битмап:
hBMP:=CreateCompatibleBitmap(MyDC,100,10 0);
Выбираю его в контекст, рисую на контексте ещё фигуры, вывожу BitBlt'ом - работает.
Но:
При попытке сделать так:
GetObject(hBMP,sizeof(BITMAP),@BMP); где BMP: BITMAP
все поля заполняются верно: тип, размер картинки, размер сканлинии в байтах, кол-во полей, разрядность пиксела, а вот последний параметр - ссылка на буфер с данными - всегда возвращается 0 (nil). В обоих случаях.
Т.е. добраться прямым доступом в буфер и записывать туда свои данные я опять не могу.
Почему не отображается ссылка на буфер? Картинки-то есть. Данные где-то в памяти хранятся, и BitBlt'ом нормально выводятся...
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
04.05.2017, 19:10
Видимо вы создали не DIB, а DDB.
Почему вы создавали битмап этой функцией? Почему в LoadImage не передаёте флаг чтоб создать диб-секцию?
1
 Аватар для CrazyDron
9 / 7 / 4
Регистрация: 08.07.2015
Сообщений: 56
04.05.2017, 23:52  [ТС]
GoodWeather,
Цитата Сообщение от GoodWeather Посмотреть сообщение
Почему вы создавали битмап этой функцией?
Наверное, потому, что ещё не обладаю необходимыми знаниями в этим вопросе.
Вчера весь гугель с яндексом выкачал, но не нашёл понятных примеров с объяснениями.
DDB ведь тоже где-то данные должен хранить, примерно таким же массивом, почему ж тогда не дать указатель на него?

Если вы найдёте время, я бы с удовольствием почитал ваши объяснения по базовой работе с GDI.
А именно - попиксельное создание собственного битмапа, его вывод (если, например, DIB не выводится простой командой SelectObject и нужно дополнительное преобразование).

Также интересует загрузка изображений из файлов разных форматов. BMP всё-таки не лучший формат для хранения.
В курсе, что GDI+ нативно работает с JPG и PNG, но я его не использую по двум причинам:
1. Код должен быть портабельным для WinCE, а там GDI+ отродясь не было.
2. Мне хотя бы просто базовые знания по GDI освоить, не говоря уже за +.
3. Видел софт для WinCE, быстро и беспроблемно ворочающий прозрачными PNG'шками.

З.Ы. В WinCE функция LoadImage есть, но она не работает. Хэндл присваивается, но при попытке вывода на экран/сохранения в файл - пусто... на ББ тот же код работает как положено.

Добавлено через 13 минут
Редактирование предыдущего сообщения уже недоступно.

Почитал ссылки, которые вы мне дали. Получается, как раз DDB мне и нужен. Как написано, он отрисовывается и обрабатывается быстрее. Таблица цветов мне не нужна. Изображение мне нужно выводить на тот же контекст, от которого я создаю новые через CreateCompatibleDC. На принтеры и прочую технику мне выводить ничего не требуется.

Добавлено через 4 часа 6 минут
Сам отвечу на свой вопрос. Поэкспериментировал и разобрался.
Средствами LCL (юнит Graphics) создаём BMP: TBitmap и массив байтов (Mas).
Заполняем массив 32-битными числами (в байтах R,G,B,A) и используем SetBitmapBits(BMP.Handle,Ширина*Высота*4 ,Mas);
Потом отрисовываем битблит с канвы BMP на нужную канву.
Пример кода:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// инициализация
  SetLength(Mas,(W*H) shl 2);
  FillChar(Mas[0],SizeOf(Mas),0);
  BMP:=Graphics.TBitmap.Create;
  BMP.Width:=W;
  BMP.Height:=H;
  BMP.PixelFormat:=pf32bit;
------------------------------------
// заполняем массив и рисуем
    for J:=0 to H-1 do
    begin
      jt:=(J*W) shl 2;
      for I:=0 to W-1 do
      begin
        it:=I shl 2;
        Mas[jt+it]:=Random(255); // Синий
        Mas[jt+it+1]:=0;         // Зелёный
        Mas[jt+it+2]:=0;        // Красный
        Mas[jt+it+3]:=0;         // Альфа-канал
      end;
    end;
    SetBitmapBits(BMP.Handle,(W*H) shl 2,Mas);
    BitBlt(Canvas.Handle,0,0,W,H,BMP.Canvas.Handle,0,0,SRCCOPY);
Вот и вся проблема.

Но обнаружилась другая неприятность:
Проц i5-3570K, винда 7 x64, экран FullHD (1920x1080).
В полноэкранном режиме Лазарус обеспечивает 25 fps. Всё падение скорости происходит на расчёте массива.

Delphi 7, тот же код, тоже полный экран. 120 fps.
No comments.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
06.05.2017, 17:38
Цитата Сообщение от CrazyDron Посмотреть сообщение
DIB не выводится простой командой SelectObject
В смысле? SelectObject выбирает объект в контекст, и ничего не "выводит".
Цитата Сообщение от CrazyDron Посмотреть сообщение
DDB ведь тоже где-то данные должен хранить
Зависит от "устройства" - "где" неизвестно, "как" тоже неизвестно - это "чёрный ящик".
Цитата Сообщение от CrazyDron Посмотреть сообщение
как раз DDB мне и нужен. Как написано, он отрисовывается и обрабатывается быстрее.
гм? Быстрее? При каких условиях и на какой платформе?
Цитата Сообщение от CrazyDron Посмотреть сообщение
В WinCE функция LoadImage есть, но она не работает.
К сожалению не могу посмотреть/проверить, нигде не имею WinCE, а вот что коды ошибок говорят смотрели?
Цитата Сообщение от CrazyDron Посмотреть сообщение
что GDI+ нативно работает с JPG и PNG
Не совсем, да, оно умеет грузить и сохранять картинку из GIF/JPEG/PNG и пары ещё каких-то, но оно просто их распаковывает и в итоге работает с битмапом.
Можно поискать либы/исходники которые умеют такое делать и засунуть в свой проект.
Цитата Сообщение от CrazyDron Посмотреть сообщение
и используем SetBitmapBits
Не рекомендовал бы, оно делает копирование. Зачем надо лишнее копирование?
Цитата Сообщение от CrazyDron Посмотреть сообщение
Средствами LCL (юнит Graphics) создаём BMP
Так если можно использовать LCL/VCL зачем было настолько глубоко в АПИ залезать?
Создаём TBitmap, ставим ему высоту, ширину, формат - и HBITMAP создано, и HDC тоже создано, и указатель и stride легко получить, лишь убеждаемся что оно имеет тип DIB.
А почему бы не использовать тип PRGBQuad?
1
 Аватар для CrazyDron
9 / 7 / 4
Регистрация: 08.07.2015
Сообщений: 56
15.10.2017, 15:18  [ТС]
Цитата Сообщение от CrazyDron Посмотреть сообщение
Но обнаружилась другая неприятность:
Проц i5-3570K, винда 7 x64, экран FullHD (1920x1080).
В полноэкранном режиме Лазарус обеспечивает 25 fps. Всё падение скорости происходит на расчёте массива.
Delphi 7, тот же код, тоже полный экран. 120 fps.
No comments.
Побуду некропостером и оффтопером

Эти полгода иногда вспоминал о таком расхождении в скорости, собирался проверить и опять забывал.

И вот вчера-таки вспомнил и нашёл время.

Перейдём сразу к концу: всё падение скорости происходит на вызове Random(). Погуглив, выяснил, что в Лазарусе используется Mersenne twister. Метод даёт прекрасные результаты, идеально равномерное распределение (сам проверял), но - требует ресурсов.
Заменил на самописный линейный конгруэнтный метод - и вуаля. Скорость поднялась на уровень Delphi.
3
15.10.2017, 19:14

Не по теме:

CrazyDron, поздравляю) и хорошо, что выложили свое решение на форум

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.10.2017, 19:14
Помогаю со студенческими работами здесь

Быстрая отрисовка в Panel ?
У меня есть очень простая программа которая на обьекте Panel рисует вот такой рисунок с помощью Polygon время за которое он это рисует...

VB6. Быстрая отрисовка графики
Добрый день всем пользователям форума. Делаю игру. на экране должно прорисовываться достаточно большое кол-во различных объектов (почти...

WPF: быстрая отрисовка и решение в целом
Задача - отрисовать небольшой фрагмент большого графа посредством WPF. Как это сделано сейчас: 1. Есть достаточно большой граф....

Отрисовка изображения
Возникла проблема с программой-фреймом. Головной менеджер в ней-CardLayout, содержащий несколько панелей. На одной из них с помощью...

Отрисовка изображения AutoScroll
Здравствуйте! У меня на форме есть панель, у панели включено свойство AutoScroll. В обработчике события Paint панели происходит...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru