簡體   English   中英

位圖為char * win32問題

[英]Bitmap to char * win32 problems

我試圖拍攝屏幕截圖,將其轉換為char *並通過winsocks發送。

我使用位圖,因為它似乎是最簡單的方法。

到目前為止,這是我得到的:

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寫入文件(我不想這樣做),則會得到一個有效的屏幕截圖。

但是,當我嘗試將位圖轉換為char *時,總是得到以下數據:

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

誰能幫我嗎?

提前致謝。

不知道為什么要將它轉換為字符串。您還可以執行當前正在做的事情,即先發送位圖的標頭。 其次是像素。 我認為沒有必要將其轉換為字符串。

這是將位圖轉換為字符串的一個非常基本的示例(為了回答問題)。

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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        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());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM