| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Звук, графика и видео > Быстрая графика |
| Автор: костярик 20.7.2006, 17:12 |
| Здравствуйте! У меня вопрос. Я часто работаю с графикой, обычно использую класс TBitmap (ScanLine). Интересно, есть ли другой, более быстрый способ вывести изображение на экран, не используя АПИ-шки типа OpenGL или DirectX. |
| Автор: Mechanic 20.7.2006, 22:46 |
| http://www.g32.org/graphics32/index.html#Downloads, например.. |
| Автор: костярик 21.7.2006, 05:11 | ||
В том-то и дело. Как вывести массив цветов на экран, наиболее быстрым образом? |
| Автор: Kesh 21.7.2006, 09:35 |
| BitBlt и FastBlt |
| Автор: Alexeis 21.7.2006, 12:01 |
| PatBlt |
| Автор: Alexeis 21.7.2006, 13:29 |
| Kesh, функция FastBlt ни где не описана, если можно - ее параметры и название динамической библиотеки. (полностью ее прототип) |
| Автор: Kesh 21.7.2006, 15:11 | ||
| Пардон, ошибся... не FastBlt, а MaskBlt Добавлено @ 15:15 Хотя все-таки нет... Склероз пока еще не убил мой мозг...
Но работает он соответственно с DDSurface'ами... |
| Автор: Alexeis 21.7.2006, 19:34 |
костярик, просил - это все таки directDraw, я понял что он хотел выводить при помощи GDI |
| Автор: костярик 21.7.2006, 20:36 | ||
Правильно, надо вывести массив цветов при помощи GDI. Тут вот BitBlt посоветовали, он копирует из одного контекста в другой. А как загнать цвета в контекст? |
| Автор: Alexeis 21.7.2006, 21:58 | ||
В него не нужно загонять просто
canvas.handle - это и есть контекст |
| Автор: костярик 22.7.2006, 06:56 | ||
Да, но у меня есть только массив из троек байтов (R, G, B) для каждого цвета. У меня еще нет канвы. Как же мне имеющийся массив загнать в контекст. TBitmap я не использую, а то, понятно, можно было б через скан лайн. Есть ли такая возможность? |
| Автор: Alexeis 22.7.2006, 16:59 |
| CreateBitmapInderect - позволяет создать битмап в памяти, затем для него можно создать свой контекст. Он называется, что-то вроде контекста для памяти. Специальный контекст, не связанный ни с каким дескриптором окна. Это чистой воды Api операции. Я попробую поискать пример - когдато делал. |
| Автор: Alexeis 22.7.2006, 17:27 | ||
А вот и пример нашел
LoadImage - Загружает картинку с диска getMem(BInfo, sizeOf(BITMAP)); - выделение памяти под структуру, которая будет использоваться для функции получения информации о битмапе - GetObject(bmp,sizeOf(BITMAP), BInfo); hBDC := CreateCompatibleDC(form1.Canvas.Handle); - создает новый контекст для структур в памяти (memory device context) т.е. для битовой маски совместимый с графическим адаптером. ипользуя в качестве образца контекст формы (подойдет любое окно). SelectObject(hBDC, bmp); - связывает дескриптор битмапа с полученным контекстом BitBlt(form1.Canvas.Handle, 0, 0, BInfo.bmWidth, BInfo.bmHeight, hBDC, 0, 0, SRCCOPY); - рисуем все что есть в контексте битмапа на контекст формы. |
| Автор: Alexeis 22.7.2006, 17:47 | ||||||||||
| А теперь рассмотрим как можно создать битмап в памяти не загружая его с диска В начале заполняем информационную структуру bmiInfo: BITMAPINFO;
Затем создаем собственно сам битмап
На этом этапе нам уже нужен контекст DC (как его получить писал выше) (lpBits : PRGBTriple;) - указатель на карту. Однако полученный битмап является DDB - Device Dependent Bitmap (не смотря на то что функция называется CreateDIBSection), что не позволяет нам н напрямую обращатся к битам карты. Поэтому мы должны его сконвертировать в DIB. Для этого заново готовим структуру bmiInfo
И получаем битмап в нужном нам формате DIB_RGB_COLORS
В параметре lpBits получаем - адрес первого байта заветной битовой карты куда можно записывать битовый масив с учетом выравнивания каждой строки битмапа на границу 4-х байт (как в файле bmp) И чтоб в этом убедится можно протестировать пикселы выводя вручную их из памяти на форму (это медленный вариант - только для тестирования
|
| Автор: костярик 24.7.2006, 10:40 | ||
| Большое спасибо вам за инфу -- как раз то, что надо. Только у меня так и не получилось обратиться к массиву битов. Ваша конструкция p^[j,i].r работать, понятно, не будет: p -- это ж у нас указатель, к тому же нетипизированный, а не массив. Тут надо хитрее поступать. Я пытался работать с массивом цветов двумя способами: как с массивом байтов и как с массивом элементов, типа TRGBTriple. Для этого пришлось объявить новый тип: TRGBTripleArray = array [1..10000] of TRGBTriple; PRGBTripleArray = ^TRGBTripleArray; Но это все равно не помогло. На экране ничего не рисуется, даже черный квадрат. Хотя bitblt возвращает true. Вот полностью весь код:
|
| Автор: Alexeis 24.7.2006, 11:12 | ||
Эта констукция не может не работать, я ее проверял, на конкретном примере, не работает что-то другое! Добавлено @ 11:25 Вот рабочий пример! |
| Автор: Alexeis 24.7.2006, 11:43 | ||||
А вот вариант почти как вам надо!
Добавлено @ 11:53 Вот тут вообще без загрузки изображения + Вывод при помощи bitblt + Вывод попиксельно из памяти указанной в p из того же битмапа
|
| Автор: welt 14.6.2009, 01:42 | ||||
| Alexeis, Ну я немного поправлю. Все-таки нехорошо, когда для разных картинок надо каждый раз вручную задавать границы массива
Я доработал код таким образом:
|
| Автор: Alexeis 14.6.2009, 20:56 | ||
Главное, что ясна суть, так нагляднее видно что это матрица, а под свою задачу каждый пусть переделывает сам |
| Автор: AntonN 14.6.2009, 21:30 |
| поправил спустя почти 3 года |