2016-01-23 2 views
0

Im пытается сделать снимок экрана, преобразовывая его в char * и отправляя его через winsocks.Bitmap to char * проблемы win32

Я использую растровые изображения, потому что это самый простой способ.

Вот что я получил до сих пор:

HDC handle_ScreenDC = GetDC(NULL); 
    HDC handle_MemoryDC = CreateCompatibleDC(handle_ScreenDC); 
    BITMAP bitmap; 
int x = GetDeviceCaps(handle_ScreenDC, HORZRES); 
int y = GetDeviceCaps(handle_ScreenDC, VERTRES); 

HBITMAP handle_Bitmap = CreateCompatibleBitmap(handle_ScreenDC, x, y); 
SelectObject(handle_MemoryDC, handle_Bitmap); 

BitBlt(handle_MemoryDC, 0, 0, x, y, handle_ScreenDC, 0, 0, SRCCOPY); 

GetObject(handle_Bitmap, sizeof(BITMAP), &bitmap); 

BITMAPFILEHEADER bmfHeader; 
BITMAPINFOHEADER bi; 

bi.biSize = sizeof(BITMAPINFOHEADER); 
bi.biWidth = bitmap.bmWidth; 
bi.biHeight = bitmap.bmHeight; 
bi.biPlanes = 1; 
bi.biBitCount = 32; 
bi.biCompression = BI_RGB; 
bi.biSizeImage = 0; 
bi.biXPelsPerMeter = 0; 
bi.biYPelsPerMeter = 0; 
bi.biClrUsed = 0; 
bi.biClrImportant = 0; 

DWORD dwBmpSize = ((bitmap.bmWidth * bi.biBitCount + 5)/32) * 4 * bitmap.bmHeight; 

HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize); 

char* bufptr = (char *) GlobalLock(hDIB); 

GetDIBits(handle_ScreenDC, handle_Bitmap, 0, (UINT) bitmap.bmHeight, bufptr, (BITMAPINFO *) &bi, DIB_RGB_COLORS); 

return bufptr; 

Теперь я получаю правильный скриншот, если я пишу HBitmap в файл (который я не хочу делать).

Однако, когда я пытаюсь преобразовать растровое изображение в символ *, я всегда получаю следующие данные:

\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\ 

Может кто-нибудь помочь мне?

Заранее спасибо.

+0

* Как * вы пытаетесь «преобразовать» изображение? И отправить его в качестве фактического «BMP» над сокетом, в котором он нуждается *, заголовки (как структуры заголовка), так и данные. –

+0

И какие пиксельные данные содержат ваше изображение - строка, которую вы shwoing, не является полностью невоспроизводимой - очевидно, в зависимости от того, как выглядит фактическое изображение, –

+0

Я пытаюсь преобразовать его в эту строку: GetDIBits (handle_ScreenDC, handle_Bitmap, 0, (UINT) bitmap.bmHeight, bufptr, (BITMAPINFO *) & bi, DIB_RGB_COLORS); – Flaime

ответ

0

Не знаете, почему вы хотите преобразовать его в строку. Вы также можете делать то, что вы сейчас делаете, что нужно сначала отправить по заголовку растрового изображения. Далее следуют пиксели. Я не вижу необходимости преобразовывать его в строку.

Вот очень простой пример преобразования растрового изображения в строку (для ответа на вопрос).

class Image 
{ 
private: 
    std::vector<std::uint8_t> Pixels; 
    std::uint32_t width, height; 
    std::uint16_t BitsPerPixel; 

public: 
    explicit Image(HDC DC, int X, int Y, int Width, int Height); 

    std::uint32_t get_width() {return width;} 
    std::uint32_t get_height() {return height;} 
    std::uint32_t get_bits_per_pixel() {return BitsPerPixel;} 
    std::string to_string(); 
}; 

Image::Image(HDC DC, int X, int Y, int Width, int Height) : Pixels(), width(Width), height(Height), BitsPerPixel(32) 
{ 
    BITMAP Bmp = {0}; 
    HBITMAP hBmp = reinterpret_cast<HBITMAP>(GetCurrentObject(DC, OBJ_BITMAP)); 

    if (GetObject(hBmp, sizeof(BITMAP), &Bmp) == 0) 
     throw std::runtime_error("BITMAP DC NOT FOUND."); 

    RECT area = {X, Y, X + Width, Y + Height}; 
    HWND Window = WindowFromDC(DC); 
    GetClientRect(Window, &area); 

    HDC MemDC = GetDC(nullptr); 
    HDC SDC = CreateCompatibleDC(MemDC); 
    HBITMAP hSBmp = CreateCompatibleBitmap(MemDC, width, height); 
    DeleteObject(SelectObject(SDC, hSBmp)); 

    BitBlt(SDC, 0, 0, width, height, DC, X, Y, SRCCOPY); 
    unsigned int data_size = ((width * BitsPerPixel + 31)/32) * 4 * height; 
    this->Pixels.resize(data_size); 

    BITMAPINFO Info = {sizeof(BITMAPINFOHEADER), static_cast<long>(width), static_cast<long>(height), 1, BitsPerPixel, BI_RGB, data_size, 0, 0, 0, 0}; 

    GetDIBits(SDC, hSBmp, 0, height, &Pixels[0], &Info, DIB_RGB_COLORS); 

    DeleteDC(SDC); 
    DeleteObject(hSBmp); 
    ReleaseDC(nullptr, MemDC); 
} 

std::string Image::to_string() 
{ 
    auto base64encode = [](std::vector<uint8_t> &in, std::string &out) -> void { 
     int i, j; 
     char *ptr; 
     uint32_t c[4]; 
     static char indexes[] = {0, 2, 1}; 
     static const char *Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

     out.resize(4 * ((in.size() + 2)/3)); 
     ptr = &out[0]; 

     for (i = 0, j = 0; i < in.size();) 
     { 
      c[0] = i < in.size() ? in[i++] : 0; 
      c[1] = i < in.size() ? in[i++] : 0; 
      c[2] = i < in.size() ? in[i++] : 0; 

      c[3] = (c[0] << 0x10) + (c[1] << 0x08) + c[2]; 

      ptr[j++] = Base64Chars[(c[3] >> 3 * 6) & 0x3F]; 
      ptr[j++] = Base64Chars[(c[3] >> 2 * 6) & 0x3F]; 
      ptr[j++] = Base64Chars[(c[3] >> 1 * 6) & 0x3F]; 
      ptr[j++] = Base64Chars[(c[3] >> 0 * 6) & 0x3F]; 
     } 

     for (i = 0; i < indexes[in.size() % 3]; ++i) 
      ptr[out.size() - 1 - i] = '='; 
    }; 

    std::string result; 
    base64encode(Pixels, result); 
    return result; 
} 

int main() 
{ 
    //.. 
    Image img(screen_dc, 0, 0, screen_width, screen_height); 
    std::string res = img.to_string(); 
    std::size_t size = res.size(); 

    //.. 
    socket.write(&screen_width, sizeof(screen_width)); 
    socket.write(&screen_height, sizeof(screen_height); 
    socket.write(&size, sizeof(size)); 
    socket.write(&res[0], res.size()); 
}