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

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

Как снимать скриншоты десктопа без тормозов


yuravss ©   (2003-02-09 16:00:00) 

Хай !
Не могу справиться с проблемой. Уже 2 сутки роюсь в MSDN и в
интернете. Вобщем выручайте !!!!!!!!!!
Пишу программу типа RAdmina (должна снимать копии экрана и их быстро
передавать по сети).
Снимки экрана я делаю., используя GDI API - каждые 100 мс:

procedure TForm1.Timer1Timer(Sender: TObject);
const BuffSize=1000;
var ScreenDC, MemDC:HDC;
Bitmap: HBITMAP;
buff: array[0..BuffSize-1] of byte;
begin
ScreenDC := GetDC(0);
MemDC := CreateCompatibleDC(ScreenDC);
Bitmap:=CreateCompatibleBitmap(ScreenDC, 1024, 768);
SelectObject(memDC,Bitmap);

BitBlt(MemDC,0,0,1024,768,ScreenDC,0,0,SRCCOPY);
GetBitmapBits(Bitmap, BuffSize, @buff); //Копируем битмап в буффер
// Некоторые действия пикселями в буффере, например пересылка буффера
в сеть
// ......
ReleaseDC(0, ScreenDC);
end;

Оно то работает, но так тормозит, что даже мышь не шевелиться в
Windows"e.
Тормоза вызваны главным образом функцией GetBitmapBits. Я ее вызываю
чтобы получить пиксели (битмап) и отправить их в сеть через сокет. Я перепробовал все примеры захвата экрана через GDI, что смог нарыть в инете и на форумах. Все они одинаково тормозят - мышь не реагирует в момент копирования (гдето около секунды или чуть меньше). Винда у меня 2000.
Помогите советом: как избавиться от тормозов. ПЛИЗЗЗЗЗЗ!!!!!!!
-------------------------
И еще вопросы:
ВОПРОС 1:
Как можно получить доступ к пикселям Bitmap после выполнения BitBlt ?
т.е я не хочу их копировать в дополнительный буффер функцией GetBitMaps.
Ведь после выполнения функции
BitBlt(MemDC,0,0,1024,768,ScreenDC,0,0,SRCCOPY) я уже получаю гдето в
памяти битовую карту Bitmap с копией десктопа.
А можно ли напрямую получить доступ к пикселям самого десктопа не
копируя их в дополнительный Bitmap ?

ВОПРОС 2:
Как мне лучше битмап передавать по сети ? Хотелось бы какой нибудь
компресии битмапа. И во вторых не хотелось бы иметь проблем с
отображением битмапа на удаленной машине (имеется ввиду апаратная
зависимость формата DDB).


bak   (2003-02-10 16:39:00) [1]

2yuravss
в РАдмине сделано всё чуток по другому
из хелпа по РАдмин

" Используется технология видеозахвата
RAdmin использует драйвер видеозахвата под Windows NT для получения изменений экрана. Это позволяет вам работать на удаленном копьютере в реальном времени с потрясающей скоростью (сотни обновлений экрана в секунду). "

зы если вдруг найдешь что по этой инфе, намыль, плиз


gsu   (2003-02-10 16:22:00) [2]

и где deleteobject


gsu   (2003-02-10 16:21:00) [3]

CreateDIBSection


i-C3H7OH   (2003-02-10 16:12:00) [4]

используй не DDB, а DIB-секции

Bitmap:=CreateCompatibleBitmap(ScreenDC, 1024, 768);
создает DDB. так как DDB хранится в адресном пр-ве ядра, достать его можно только скопировав в АП нашего приложения с помощью GetBitmapBits. а DIB-секции хранятся как раз в АП нашего приложения, но в отличие от DIB поддерживают операции GDI. как пользоваться DIB-секциями см исходники FastLIB

а по сети передавать будем DIB , с заголовком и тп, разве нет?
можно преобразовать его в рсх


yuravss   (2003-02-10 15:01:00) [5]

for bak:
Низкий приоритет ничего не даст.
Для копирования пикселей из видеопамяти в мой буффер винда переходит в режим ядра. В этом режиме она скорее всего становиться однозадачно. А так как копирование это достаточно длинная процедура, то и замечаеться завмирание мыши в момент выполнения bitblt.
P.S. Это не троян, а программа для админов типа Radmin

for Cobalt:
Функция GetBitmapBits не потому тормозит, что старая уже. Новая GetDIBits тоже тормозит. Это все из-за копирования в режиме ядра.

Но как бороться с этим без DirectDraw ????


Cobalt   (2003-02-10 09:07:00) [6]

The GetBitmapBits function is not implemented in the Win32 API. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the GetDIBits function.


bak   (2003-02-10 09:03:00) [7]

уменьши приоритет своего приложения (поставь ему Idle); компрессируй свой битмап например в jpeg; исполъзуй свойство битмапа PixelFormat или (я правда не разбирался) можешь поробовать DXDIB из DelphiX.


bm:= TBitMap.Create;
bm.PixelFormat:= pf8bit;
PStream:= TMemoryStream.Create;
bm.Width:= Screen.Width;
bm.Height:= Screen.Height;
BitBlt(bm.Canvas.Handle, 0, 0,
bm.Width, bm.Height,
GetDC(0), 0, 0, SRCCOPY);
Bm.SaveToStream(PStream);
Bm.Free;


зы Лошадь пишешь, а? :)


Наверх

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