Введение: пытаюсь сделать программу, которая бы задействовала Uvnc-зеркальный-драйвер на сервере, с целью перехвата изменений и отображения оных на клиентских тачках на TImage. Пока что у меня получается отправлять не изменения, а весь экран, с помощью зеркального дравера Но есть проблема.
Проблема: загрузка процессора у клиента 40-50%.
Без масштабирования и отображения изображения полученного от сервера загрузка процессора 3%.
Отсюда я делаю вывод, что виновато либо масштабирование изображения (полученный скриншот->РазмерTImage), либо отображение на TImage. Однако, отображение маленькой части изображаги = загрузка процессора<10%. Отсюда делаем вывод, что виновато масштабирование.
Пути решения перепробаванные мной:
1) StretchBlt. Загруженность проца: 50-60%. При использовании SetStretchBltMode(dcWnd,COLORONCOLOR); Ситуация улучшается до 30-40%, но качество картинки ухудшается очень сильно.
2) Stretchdibits. Примерно то же самое, что 1)
3) setdibitstodevice. Насколько я понял - аналогична BitBlt, и вообще-то ничего не масштабирует.
4) И последнее пока что самое лучшее решение, которое у меня сработало, это:
С помощью CreateDIBSection указываем переменную в которую загружаются данные от сервера.
И с помощью form1.image1.picture.bitmap.canvas.changed; обновляем TImage. Заруженность процессора 20-30%. Качество картинки - отличное.
Вот основной код:
Примечание: прием изображаги выполнен с использованием TCP/IP техонологии Synapse. =)
- Код: Выделить всё
....
imgBMPDC:=form1.image1.picture.bitmap.canvas.handle;
form1.image1.picture.bitmap.Handle:=CreateDIBSection(imgBMPDC,BInfo,DIB_RGB_COLORS,bits,0,0);
....
while (not(stop) and (sock.lasterror=0))do
begin
//Говорим серверу, что хотим от него кадр =)
sock.SendBuffer(@ok, SizeOf(string[2]));
tmp:=0;
//Принимаем изображагу. Для тестов принимаю только несколько строчек изображения. Размер = 50*1152*2, начиная с 256 строчки.
//1152-Width,
//2-глубина цвета
//50-количество строчек
//Цикл - чуть голову себе не сломал, но написал: ПринимаетСколькоВлезет*минус*СколькоУжеВлезло :D :D
while ((tmp<50*1152*2)and(sock.lasterror=0))do tmp:=Sock.RecvBuffer(bits+256*1152*2+tmp,50*1152*2-tmp)+tmp;
if tmp=0 then continue;
//обновить изображение
form1.image1.picture.bitmap.canvas.changed;
end;
Инструментарий: Lazarus 0.9.31-29597-fpc-2.5.1. ОС: Windows XP
Целевая машина: Одноядерный Celeron 1.7 Гц, 256 мб оперативки. Видюха тоже старая.
Чё я вообще хочу: пока читал лит-ру по проблеме - везде советуют переходить на Opengl или Directx, потому что они более честно используют ресурсы компьютера. Мне больше нравится Opengl (бесплатный и кроссплатформенный). Но тогда придётся переписывать ВЕСЬ код (ну т.е. большую часть). А я ещё слабенький в программировании - мне этот-то код очень сложно было написать. Нашёл в интернете функцию gluScaleImage - раз проблема в масштабировании, то эта функция должна помочь я думаю...
Внимание вопрос: мне поможет gluScaleImage? И второй вопрос: что должно быть в программе, чтобы я смог использовать gluScaleImage. Т.е. мне ведь весь функционал Opengl не нужен - только вот эта маленькая процедурка, не мог бы кто-нибудь написать минимум, который должен быть в программе, чтобы заюзать gluScaleImage. Всем заранее спасибо..