Сжимать скрины для передачи по сети

Тема в разделе "WASM.WIN32", создана пользователем Flasher, 29 окт 2008.

  1. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Есть программая которая делает скрины и сохраняет в файл у клиента. (bmp)
    Задача - сжимать скрины и передать по сети серваку.
    Я пока не знаю по какому пути пойти.

    Вот идеи:
    1) перехватить функцию GetDIBits и налету как-то испортить качество передаваемых данных, чтоб прога уже сохранила скрин в сжатом виде.
    2) взять файл скрина, который весит от 1 до 3 мб, сжимать через какой-нить алгоритм, тпа lzw, zip и т.д., и отправить серву.
    3) взять файл скрина, испортить качество и отправить серву.
    4) делать всё как на первом пукнте, токо в файл не сохранять, сразу отправить серверу. (этот способ мне особенно подуше)

    Второй метод мне не нравится, потому что потом на серве для просмотра скринов придется юзать декомпрессатор, это не удобно.

    Что посоветуйте?
    И где можно нарыть схожие исходники по ухудщению качества изображения bmp файлов ?
    Почитал структура bmp в Википедии, ничего полезного для себя не вынес.
     
  2. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    блин, делать жпг, пнг, гиф. есть отдельные либы, а есть фриимаж и еще есть дофига
     
  3. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Прошу воздержаться от обстрактных ответов :)
     
  4. G0L1a7h

    G0L1a7h New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2008
    Сообщения:
    41
    http://hellknights.void.ru/articles/0x48k-VisualSpy.htm
     
  5. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Flasher
    В смысле за тебя код написать?

    GDI+ API. Конвертация в PNG
     
  6. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    GDI+ не катит, не поддерживается везде.
     
  7. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    неохота както даже снова писать. фриимаж. английскими буквами переписать это слово можете? суете ему бмп в памяти, говорите что и он вам конвертит в 10ток форматов по выбору. Есть вырезки из него в сети. Есть другие либы жпг, гиф - так вообще простой и маленький. Тут на форуме обсуждалось, на сайте либы лежат. А бмп - громоздкий формат. Даже за7зипуйте его и жпг все равно меньше будет.
     
  8. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Кста, если на экране окна с кнопками, то loseless .png будет меньше .jpg. Ну а если разговор идёт про что-то VNC-обозное, то надо посылать изменения между скринами, но это на много сложнее.
     
  9. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    положи вместе с прогой ДЛЛку gdiplus.dll
     
  10. Dian

    Dian Member

    Публикаций:
    0
    Регистрация:
    19 июн 2008
    Сообщения:
    222
    Flasher
    Можно воспользоваться тем, что большинство кадров будут похожи и заюзать дельта кодирование, поверх него - какой-нибудь стандартный алгоритм
     
  11. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Dian, кадры не одинаковые..
    K10, не хорошо тащить за собой dll :P
    _basmp_, не хочу юзать левые либы..

    В общем я решил сам сфотать экран и отсылать.

    Фотаю вот так:

    Код (Text):
    1. .data
    2. sbuffer dd 0
    3. slen dd 0
    4.  
    5. .code
    6. CapScreen proc uses edi esi ebx
    7.      local hdc:HDC
    8.      local memdc:HDC
    9.      local hBitmap:dword
    10.      local dwWidth:dword
    11.      local dwHeight:dword
    12.  
    13.        invoke GetDC,0
    14.        mov hdc,eax
    15.        invoke CreateCompatibleDC,hdc
    16.        mov memdc,eax
    17.        invoke GetDeviceCaps,hdc,HORZRES
    18.        mov dwWidth,eax
    19.        invoke GetDeviceCaps,hdc,VERTRES
    20.        mov dwHeight,eax
    21.  
    22.        mov eax,dwWidth
    23.        mov ecx,dwHeight
    24.        mul ecx
    25.        mov ecx,16
    26.        mul ecx
    27.        shr eax,3
    28.        add eax,sizeof BITMAPFILEHEADER
    29.        add eax,sizeof BITMAPINFOHEADER
    30.        mov slen,eax
    31.  
    32.        invoke GlobalAlloc,40h,eax
    33.        mov sbuffer,eax
    34.        mov edi,sbuffer
    35.        
    36.        mov (BITMAPFILEHEADER ptr [edi]).bfType,4D42h
    37.        mov eax,slen
    38.        mov (BITMAPFILEHEADER ptr [edi]).bfSize,eax
    39.        mov (BITMAPFILEHEADER ptr [edi]).bfOffBits,sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER
    40.        
    41.        add edi,sizeof BITMAPFILEHEADER
    42.        mov (BITMAPINFOHEADER ptr [edi]).biSize,sizeof BITMAPINFOHEADER
    43.        push dwWidth
    44.        pop (BITMAPINFOHEADER ptr [edi]).biWidth
    45.        push dwHeight
    46.        pop (BITMAPINFOHEADER ptr [edi]).biHeight
    47.        mov (BITMAPINFOHEADER ptr [edi]).biPlanes,1
    48.        mov (BITMAPINFOHEADER ptr [edi]).biBitCount,16
    49.        mov (BITMAPINFOHEADER ptr [edi]).biCompression,BI_RGB
    50.  
    51.        invoke CreateCompatibleBitmap,hdc,dwWidth,dwHeight
    52.        mov hBitmap,eax
    53.        invoke SelectObject,memdc,hBitmap
    54.        invoke BitBlt,memdc,0,0,dwWidth,dwHeight,hdc,0,0,SRCCOPY
    55.  
    56.        mov ecx,edi
    57.        add edi,sizeof BITMAPINFOHEADER
    58.        invoke GetDIBits,memdc,hBitmap,0,dwHeight,edi,ecx,0
    59.        
    60.        invoke DeleteObject,hBitmap
    61.        invoke DeleteDC,memdc
    62.        invoke DeleteDC,hdc
    63.        ret
    64. CapScreen endp
    65.        
    66. szFileName db "screen.bmp",0
    67.  
    68. start proc
    69.        invoke DeleteFileA,offset szFileName
    70.        invoke _lcreat,offset szFileName,0
    71.        mov esi,eax
    72.        call CapScreen
    73.        invoke _lwrite,esi,sbuffer,slen
    74.        invoke _lclose,esi
    75.        invoke GlobalFree,sbuffer
    76.        invoke ExitProcess,0
    77. start endp
    78. end start
    Подскажите плиз как сделать разрешение любого скрина на 720x576, плюс еще чуточку испортить качество, думаю если будет весить не больше 200кб, вполне приемлимо.

    Спасибо.
     
  12. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Вроде API'шная ф-ия есть. Или сам напиши (да и в нете полно кода).

    Простые способы:
    1) уменьшить разрешение битмапа
    2) 32bit -> 16bit (или вовсе -> 8bit , правда палитру придётся исчо юзать)
    Посложнее:
    1) прилинковать к проекту исходники JPEG или GIF

    Юзай JPEG и будет тебе счастье.
     
  13. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Flasher
    как сделать разрешение любого скрина на 720x576
    У тебя два dc (экран и compatible dc), второй сразу делай размером 720x576, при копировании из первого во второй вместо BitBlt используй StretchBlt.
     
  14. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    q_q, сделал..

    810кб начал весить..

    Код (Text):
    1. .data
    2. sbuffer dd 0
    3. slen dd 0
    4.  
    5. .code
    6. CapScreen proc uses edi esi ebx
    7.      local hdc:HDC
    8.      local memdc:HDC
    9.      local hBitmap:dword
    10.      local dwWidth:dword
    11.      local dwHeight:dword
    12.      
    13.        mov eax,720
    14.        mov ecx,576
    15.        mul ecx
    16.        mov ecx,16
    17.        mul ecx
    18.        shr eax,3
    19.        add eax,sizeof BITMAPFILEHEADER
    20.        add eax,sizeof BITMAPINFOHEADER
    21.        mov slen,eax
    22.  
    23.        invoke GlobalAlloc,40h,eax
    24.        mov sbuffer,eax
    25.        mov edi,sbuffer
    26.        
    27.        mov (BITMAPFILEHEADER ptr [edi]).bfType,4D42h
    28.        mov eax,slen
    29.        mov (BITMAPFILEHEADER ptr [edi]).bfSize,eax
    30.        mov (BITMAPFILEHEADER ptr [edi]).bfOffBits,sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER
    31.        add edi,sizeof BITMAPFILEHEADER
    32.        mov (BITMAPINFOHEADER ptr [edi]).biSize,sizeof BITMAPINFOHEADER
    33.        mov (BITMAPINFOHEADER ptr [edi]).biWidth,720
    34.        mov (BITMAPINFOHEADER ptr [edi]).biHeight,576
    35.        mov (BITMAPINFOHEADER ptr [edi]).biPlanes,1
    36.        mov (BITMAPINFOHEADER ptr [edi]).biBitCount,16
    37.        mov (BITMAPINFOHEADER ptr [edi]).biCompression,BI_RGB
    38.  
    39.        invoke GetDC,0
    40.        mov hdc,eax
    41.        invoke CreateCompatibleDC,hdc
    42.        mov memdc,eax
    43.        invoke CreateCompatibleBitmap,hdc,720,576
    44.        mov hBitmap,eax
    45.        invoke SelectObject,memdc,hBitmap
    46.  
    47.        invoke GetDeviceCaps,hdc,HORZRES
    48.        mov dwWidth,eax
    49.        invoke GetDeviceCaps,hdc,VERTRES
    50.        mov dwHeight,eax
    51.        invoke StretchBlt,memdc,0,0,720,576,hdc,0,0,dwWidth,dwHeight,SRCCOPY
    52.  
    53.        mov ecx,edi
    54.        add edi,sizeof BITMAPINFOHEADER
    55.        invoke GetDIBits,memdc,hBitmap,0,576,edi,ecx,0
    56.        
    57.        invoke DeleteObject,hBitmap
    58.        invoke DeleteDC,memdc
    59.        invoke DeleteDC,hdc
    60.        ret
    61. CapScreen endp
    62.        
    63. szFileName db "screen.bmp",0
    64.  
    65. start proc
    66.        invoke DeleteFileA,offset szFileName
    67.        invoke _lcreat,offset szFileName,0
    68.        mov esi,eax
    69.        call CapScreen
    70.        invoke _lwrite,esi,sbuffer,slen
    71.        invoke _lclose,esi
    72.        invoke GlobalFree,sbuffer
    73.        invoke ExitProcess,0
    74. start endp
    75. end start
    Могет еще что можно сделать ?
    Например... могет юзать еще и вместо GetDIBits -> StretchDIBits
    Или это уже совсем не то ?
     
  15. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Flasher, тебе ж нескольно раз сказали - перекодируй bitmap в нормальный формат. Например:
    http://www.libpng.org/pub/png/libpng.html
     
  16. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    s0larian, та это процедура скрина у мя будет как shellcode в памяти другого процесса, память не резиновая чтоб туда пихать еще и либы перекодировщиков..
    Внедрял бы я свою dll, другое дело, а так.., мне подходят лишь подручные средства gdi.
     
  17. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Flasher
    Несложный кодировщик png/jpeg несложно засунуть в pic
     
  18. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Не помню чие творчество. Когото с форума. Автор! Отзовись! Имею ли я право твое творение выкладывать?
     
  19. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Flasher

    а сжимать посылаемые данные аплибом не хочешь ? а потом разжимать ?
    _basmp_
    что это за исходник ? ... я когда то тему заводил , искал компрессор и декопрессор джпег.
     
  20. KondraT

    KondraT Member

    Публикаций:
    0
    Регистрация:
    22 янв 2006
    Сообщения:
    175
    У меня тоже была проблемка как делать скрины экрана и передавать их по сети.

    Bmp по весу большой получался, тем более мне надо скрины ловить не с одной машины... Решил заюзать lzw алгоритм. Очень хороший результат получил для сжатия bmp формата. Так что вариант 2.