Передать картинку по сокету
От: elGray  
Дата: 01.12.05 22:28
Оценка:
Требуется сабж. Подскажите, как это лучше сделать?
У меня на входе есть HDC и HBITMAP. Что передавать? Догадываюсь, что нужно заполнить структуру BITMAP (через GetObject наверное) и ее передавать. А как ее потом опять нарисовать на выходе? Т.е. преобразовать обратно в HBITMAP, HDC ?
Есть мысль создавать полный bmp-файл и потом его передавать, грузить и показывать, то я думаю, это извращение
Может, есть какие то более экономные, так сказать, методы — ради скорости и экономии трафика? Устраивает некоторое потяря качетсва, или, например, сжать ее до 50% по размерам, передать в формате jpeg...
Что то я запутался
Подмогните, куда копать хотя бы.
Спасибо
Re: Передать картинку по сокету
От: ekamaloff Великобритания  
Дата: 02.12.05 03:14
Оценка: 2 (1)
Здравствуйте, elGray, Вы писали:

G>Требуется сабж. Подскажите, как это лучше сделать?

G>У меня на входе есть HDC и HBITMAP. Что передавать? Догадываюсь, что нужно заполнить структуру BITMAP (через GetObject наверное) и ее передавать. А как ее потом опять нарисовать на выходе? Т.е. преобразовать обратно в HBITMAP, HDC ?

Если на входе DDB, преобразуйте в DIB и передавайте. Если на входе DIB то и преобразовывать ничего не надо. HDC не трогайте, она тут ни при чем.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[2]: Передать картинку по сокету
От: elGray  
Дата: 02.12.05 10:28
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Здравствуйте, elGray, Вы писали:


G>>Требуется сабж. Подскажите, как это лучше сделать?

G>>У меня на входе есть HDC и HBITMAP. Что передавать? Догадываюсь, что нужно заполнить структуру BITMAP (через GetObject наверное) и ее передавать. А как ее потом опять нарисовать на выходе? Т.е. преобразовать обратно в HBITMAP, HDC ?

E>Если на входе DDB, преобразуйте в DIB и передавайте. Если на входе DIB то и преобразовывать ничего не надо. HDC не трогайте, она тут ни при чем.


Э... как это HDC не трогать? На входе "скриншот", полученный через GetDC. Что вы имеете в виду?
Я так понимаю, что нужно передавать BITMAPINFOHEADER ? Вроде накопал в МСДН, как их туда-обратно пребразовывать.
Re[3]: Передать картинку по сокету
От: ekamaloff Великобритания  
Дата: 02.12.05 10:42
Оценка:
Здравствуйте, elGray, Вы писали:

G>Э... как это HDC не трогать? На входе "скриншот", полученный через GetDC. Что вы имеете в виду?

G>Я так понимаю, что нужно передавать BITMAPINFOHEADER ? Вроде накопал в МСДН, как их туда-обратно пребразовывать.

HDC — это такая виртуальная штука, позволяющая рисовать на различных устройствах используя единый упрощенный интерфейс. Передавать ее по сети смысла нет, поскольку это всего лишь хендл и на другом компе смысла иметь не будет.

Далее, я так понимаю вы получаете скриншот вот таким образом:

HDC hdc = GetDC(NULL);


Теперь вам нужно создать еще один контекст в памяти (CreateCompatibleDC) и битмап (CreateCompatibleBitmap). Выбрать этот битмап в ваш контекст. Скопировать все с контекста экрана (hdc) в ваш мемори контекст (BitBlt). Теперь создаете на основе вашего битмапа (он же DDB) девайсо независимый битмап (DIB, см. ф-цию GetDIBits) и его уже передаете по сокету. Про формат DIB придется немного почитать, он довольно сложен для того, чтобы здесь описывать.

Ну вот примерно так, возможны мелкие неточности.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re: Передать картинку по сокету
От: qwe_asd_zxc Россия  
Дата: 02.12.05 10:51
Оценка: 2 (1)
класс для работы с Jpeg
здесь

библиотека ijl.dll:
здесь

преобразуй HBITMAP в DIB:

BOOL CBmpFile::LoadFromHBitmap(HBITMAP hBitmap, WORD biBitCount)
{
    BITMAP bmInfo;
    int nRes = GetObject(hBitmap, sizeof(bmInfo), &bmInfo);
    if (nRes != sizeof(bmInfo))
        return FALSE;

    // prepare header

    m_lpBMI = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, 
        sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 0x100);
    if (m_lpBMI == NULL) return FALSE;

    LPBITMAPINFOHEADER lpBMIH = &m_lpBMI->bmiHeader;

    lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
    lpBMIH->biWidth = m_cxBmp = bmInfo.bmWidth;
    lpBMIH->biHeight = m_cyBmp = bmInfo.bmHeight;
    lpBMIH->biPlanes = 1;
    lpBMIH->biBitCount = (biBitCount) ? biBitCount : bmInfo.bmBitsPixel;
    lpBMIH->biCompression = BI_RGB;

    // prepare image data

    m_dwBytesPerScanLine = ((DWORD) m_cxBmp * m_lpBMI->bmiHeader.biBitCount) / 32;
    if (((DWORD) m_cxBmp * m_lpBMI->bmiHeader.biBitCount) % 32)
        m_dwBytesPerScanLine++;
    m_dwBytesPerScanLine *= 4;

    m_dwSizeBmpImage = m_dwBytesPerScanLine * m_cyBmp;

    m_lpBmpImage = (LPBYTE) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, m_dwSizeBmpImage);
    if (m_lpBmpImage == NULL)
    {
        LocalFree(m_lpBMI);
        m_lpBMI = NULL;
        return FALSE;
    }

    // get image data

    HDC hdcScreen = CreateDC( _T("DISPLAY"), NULL, NULL, NULL );
    int nLines = GetDIBits(hdcScreen, hBitmap, 0, m_cyBmp, m_lpBmpImage, m_lpBMI, DIB_RGB_COLORS);
    DeleteDC(hdcScreen);

    if (nLines != m_cyBmp)
    {
        DestroyBmpImage();
        return FALSE;
    }

    return TRUE;
}


загони полученные данные в jpeg и передай их по сети.
затем разожми и отобрази:


HBITMAP CBmpFile::GetHBitmap()
{
    if (!m_lpBMI || !m_lpBmpImage)
        return NULL;

    m_lpBMI->bmiHeader.biSizeImage = m_dwSizeBmpImage;

    LPVOID pvBits;
    HBITMAP hBitmap = NULL;

    // create hbitmap from image data

    HDC hdcScreen = CreateDC( _T("DISPLAY"), NULL, NULL, NULL );
    hBitmap = CreateDIBSection(hdcScreen, m_lpBMI, DIB_RGB_COLORS, &pvBits, NULL, 0);
    DeleteDC(hdcScreen);

    if (hBitmap != NULL)
        memcpy(pvBits, m_lpBmpImage, m_dwSizeBmpImage);

    return hBitmap;
}
Re[4]: Передать картинку по сокету
От: Pavel Dvorkin Россия  
Дата: 02.12.05 10:53
Оценка: 1 (1)
Здравствуйте, ekamaloff, Вы писали:

E>Теперь вам нужно создать еще один контекст в памяти (CreateCompatibleDC) и битмап (CreateCompatibleBitmap). Выбрать этот битмап в ваш контекст. Скопировать все с контекста экрана (hdc) в ваш мемори контекст (BitBlt). Теперь создаете на основе вашего битмапа (он же DDB) девайсо независимый битмап (DIB, см. ф-цию GetDIBits) и его уже передаете по сокету. Про формат DIB придется немного почитать, он довольно сложен для того, чтобы здесь описывать.


Я бы вместо CreateCompatibleBitmap и GetDIBits обошелся бы одним вызовом CreateDIBSection
With best regards
Pavel Dvorkin
Re[2]: Передать картинку по сокету
От: Роман Дубров Украина Я@Blogspot
Дата: 02.12.05 11:04
Оценка: +1
qwe_asd_zxc wrote:

> класс для работы с Jpeg

> здесь <http://www.sources.ru/cpp/cpp_class_for_jpeg.shtml&gt;

тогда уже лучше в png, хоть потери качества не будет.
А скриншоты в жпеге ацтойно смотрятся.....

--
np: [foobar2000] not started
Posted via RSDN NNTP Server 2.0
http://www.linkedin.com/in/romandubrov .::. http://roman-dubrov.blogspot.com/ .::. http://www.flickr.com/photos/romandubrov/
Re[4]: Передать картинку по сокету
От: elGray  
Дата: 02.12.05 11:25
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Ну вот примерно так, возможны мелкие неточности.


Эт понятно. То, что HDC — это дескриптор контекста а не оно само, я знаю. Мне показалось, что вы имеете в виду _вообще_ HDC не трогать

В общем, я нашел в МСДН описание всей этой штуки.
Только вот или я что-то пропустил, или чего то не понял... есть способы, имея только HDC, получить его HBITMAP? Я имею в виду без создания нового в памяти, получить через GetDC, вытащить его HBITMAP и сразу с ним работать? Или все таки "выгоднее" создавать копию в памяти?
Re[2]: Передать картинку по сокету
От: elGray  
Дата: 02.12.05 11:28
Оценка:
Здравствуйте, qwe_asd_zxc, Вы писали:

пасибо, дома попоробую
Re[3]: Передать картинку по сокету
От: elGray  
Дата: 02.12.05 11:29
Оценка:
Здравствуйте, Роман Дубров, Вы писали:

РД>qwe_asd_zxc wrote:


>> класс для работы с Jpeg

>> здесь <http://www.sources.ru/cpp/cpp_class_for_jpeg.shtml&gt;

РД>тогда уже лучше в png, хоть потери качества не будет.

РД>А скриншоты в жпеге ацтойно смотрятся.....

РД>--

РД>np: [foobar2000] not started

А как в пнг затолкать битмап?
Re[5]: Передать картинку по сокету
От: ekamaloff Великобритания  
Дата: 02.12.05 11:33
Оценка:
Здравствуйте, elGray, Вы писали:

G>В общем, я нашел в МСДН описание всей этой штуки.

G>Только вот или я что-то пропустил, или чего то не понял... есть способы, имея только HDC, получить его HBITMAP? Я имею в виду без создания нового в памяти, получить через GetDC, вытащить его HBITMAP и сразу с ним работать? Или все таки "выгоднее" создавать копию в памяти?

GetDIBSection. Уже сказали вот тут
Автор: Pavel Dvorkin
Дата: 02.12.05
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[4]: Передать картинку по сокету
От: Pavel Dvorkin Россия  
Дата: 02.12.05 11:37
Оценка:
Здравствуйте, elGray, Вы писали:

G>А как в пнг затолкать битмап?


Через GDI+ можно.
With best regards
Pavel Dvorkin
Re[3]: Передать картинку по сокету
От: qwe_asd_zxc Россия  
Дата: 02.12.05 12:13
Оценка:
Здравствуйте, Роман Дубров, Вы писали:

РД>qwe_asd_zxc wrote:


>> класс для работы с Jpeg

>> здесь <http://www.sources.ru/cpp/cpp_class_for_jpeg.shtml&gt;

РД>тогда уже лучше в png, хоть потери качества не будет.

РД>А скриншоты в жпеге ацтойно смотрятся.....

РД>--

РД>np: [foobar2000] not started

c png не работал, поэтому спорить не буду.
посоветовал то, что уже делал и в чем уверен, что будет работать.
РД>А скриншоты в жпеге ацтойно смотрятся.....
в скриншоте может и ..., а в реале очень ничего.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.