[英]Bitmap to char * win32 problems
Im trying to take a screenshot, converting it to a char * and sending it via winsocks. 我试图拍摄屏幕截图,将其转换为char *并通过winsocks发送。
I use bitmaps because it appears to be the easiest way. 我使用位图,因为它似乎是最简单的方法。
Heres what I got so far: 到目前为止,这是我得到的:
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;
Now, I get a valid screenshot if I write hBitmap to a file ( which I do not want to do ). 现在,如果我将hBitmap写入文件(我不想这样做),则会得到一个有效的屏幕截图。
However, when I try to convert the Bitmap to a char *, I always get the following data: 但是,当我尝试将位图转换为char *时,总是得到以下数据:
\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\x1\x1\x1ÿ\
Can anyone help me out? 谁能帮我吗?
Thanks in advance. 提前致谢。
Not sure why you want to convert it to a string.. You could also do what you're currently doing which is to send over the header of the bitmap first. 不知道为什么要将它转换为字符串。您还可以执行当前正在做的事情,即先发送位图的标头。 Followed by the pixels. 其次是像素。 I don't see the need to convert it to a string. 我认为没有必要将其转换为字符串。
Here is a very basic example of converting the bitmap to a string (for the sake of answering the question). 这是将位图转换为字符串的一个非常基本的示例(为了回答问题)。
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.