![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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 );