Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

BitBlt работает медленно при захвате с одним качеством и... [Win95/98, Win2k, WinXP]


DenisSM ©   (2003-10-31 11:44:00) 

День добрый всем.

Необоходимо захватить содержимое экрана и преобразовать его в 24-битовый bmp. BitBlt работает медленно если color quality не соответствует 24 битам. Что можно предпринять?

Заранее благодарен за ответ (кидайте и почтой).

Док.


miek   (2003-11-03 20:14:00) [1]

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


cmpxchg8   (2003-11-02 11:54:00) [2]

2all чтож, ребята придется маленькую статью про SSE и Дельфи накропать, уж совсем наболело, а если совсем не терпиться - смотрите JEDI lib


Romaa   (2003-11-01 10:19:00) [3]

CMPXCHG8 © (01.11.03 00:09) [6]
Пример можна ??...


CMPXCHG8   (2003-11-01 00:09:00) [4]

2miek ;-) верно
2DenisSM 1. почему стобственно 24? при 32 - быстрее доступ, каждый пиксель выровнен на границу DWORD - при больших массивах данных это даже очень корошо, хотя жрет больше памяти

Попробуй так:
---
HDC hdcDest = CreateCompatibleDC(0);
// один к одному - лучше, потому как при преобразованиях winь постоянно читает видеопамять а она не кэшируется
HBitmap hBbmp = CreateCompatibleBitmap(hdcDest,w,h);

SelectObject(hdcDest,hBmp);
bitBlt(hdcDest, 0, 0, w, h, hdcScreen, 0,0, SRCCOPY);
----
а далее - конвертируй в обычной памяти как угодно, можешь через тот же bitBlt, можешь свою процедуру написать что лучше, так как winевский blitter использует масочное умножение:
Mask.Red, Mask.Green, Mask. Blue
RGB:= RGB((Color and Mask.Red)* 255 / Mask.Red),
(Color and Mask.Green)* 255 / Mask.Green),
(Color and Mask.Blue)* 255 / Mask.Blue))
представь так над каждым пикселем? - медленно
а если задействовать MMX или SSE - раза в 2 быстрее минимум получится


miek   (2003-10-31 20:34:00) [5]

Захватывать картинку быстрым способом, а потом конвертировать своей собственной процедурой.


DenisSM   (2003-10-31 14:20:00) [6]

не - это не вариант. Очевидно, что преобразование - причина задержки. Тут я уже веду обсуждение по поводу двойной буфферизации. Вот кусок диалога, но как это воплотить правильно, я не в курсе. %-(
-----------
У тебя происходит прямое преобразование изображения при чтении его из контекста экрана в контекст в памяти. Вот тут-то скорее всего и проблема. Дело в том, что если карточка такой режим не поддерживает (а поддерживают его не многие карточки), то обработка идёт програмно, а если ещё и карточка стоит на медленной шине, то тут совсем медленно всё работает.
Я бы попробовал двойную буферизацию. Сначала захватывать изображение в совместимый с дисплеем контекст в памяти (это должно работать очень быстро), а затем преобразовать картинку в другой контекст в памяти. Тут все должно работать гораздо быстрее. Хотя памяти требуется больше.
-----------


ZEE   (2003-10-31 14:08:00) [7]

как вариант - можно проверить скока времени будет тратится на фотографирование+преобразование если не создавать битмап каждый раз, а создать его где-то, в криэйте например - потом его поюзать и убить где-то в дестрое...
не уверен, что так быстрее, но все может быть...


DenisSM   (2003-10-31 12:47:00) [8]

Абсолютная правда, но дело именно в том, что мы захватываем 16-24-32 битный экран, а получить должны 24-битный, так как именно он является стандартом (это долгая история). Захват действительно "мгновенен" - у меня порядка 0.009 сек получается с записью на диск в png формате при разрешении 1600X1200 с 24 битами. Но при конвертации в 24 это занимает 1.5 секунды!!!

Это схематически выгдяжит так:

HDC hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
HGDIOBJ old;
int w = GetDeviceCaps(hdcScreen, HORZRES);
int h = GetDeviceCaps(hdcScreen, VERTRES);
HDC hdcDest = CreateBMP( w, h, 24, old);
BITMAP bmp;
BitBlt(hdcDest, 0, 0, w, h, hdcScreen, 0,0, SRCCOPY);

Назначение CreateBMP, полагаю, ясно - 24 битовая с размерами w,h.

Причина мне также понятна (надеюсь она верна :-) ). Важно осознать, как это "побороть". Вот тут я и прошу совета.


ZEE   (2003-10-31 12:35:00) [9]

ИМХО: BitBlt работает не медленно - медленно преобразование проходит...
зы: я попробовал - на 16бит BitBlt "фотографирует" экран мгновенно (как для меня), разве что можт это "мгновенно" - не подходит, а надо еще быстрее :)

BitBlt(Canvas.Handle, 0,0,Screen.Width,Screen.Height,ScreenDC, 0, 0, SRCCOPY );


Наверх

Титульная страница Поиск, карта сайта Написать письмо