HBitmap字节数组到php

HBitmap字节数组到php,php,c++,winapi,base64,Php,C++,Winapi,Base64,我正试图以以下方式在我的控制台win32应用程序中制作屏幕截图: char* getScreenshot(){ HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL); HDC hMemoryDC = CreateCompatibleDC(hScreenDC); int x = GetDeviceCaps(hScreenDC, HORZRES); int y = GetDeviceCaps(hScreenDC,

我正试图以以下方式在我的控制台win32应用程序中制作屏幕截图:

char* getScreenshot(){
    HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int x = GetDeviceCaps(hScreenDC, HORZRES);
    int y = GetDeviceCaps(hScreenDC, VERTRES);

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
    size_t width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    size_t height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
    char* buffer = new char[x*y]();
    GetBitmapBits(hBitmap,x*y,buffer);
    DeleteDC(hMemoryDC);
    DeleteDC(hScreenDC);
    return buffer;
}
char *buff = getScreenshot();
string a(buff);
send(hClientSocket, buff, a.length(), 0);
if (hClientSocket!=INVALID_SOCKET)
    closesocket(hClientSocket);     
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
set_time_limit(15);
$succ = socket_connect($sock, $ip, $port) or die("timeout");
$output = "";
while($resp = socket_read($sock, 1000)) {
   $output .= $resp;
}
socket_close($sock);
$base64 = base64_encode($output);
echo "<img src='data:image/bmp;base64,$base64' />";
缓冲区应该是包含hbitmap屏幕截图的字节数组

然后我通过一个插座以这种方式发送:

char* getScreenshot(){
    HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int x = GetDeviceCaps(hScreenDC, HORZRES);
    int y = GetDeviceCaps(hScreenDC, VERTRES);

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
    size_t width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    size_t height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
    char* buffer = new char[x*y]();
    GetBitmapBits(hBitmap,x*y,buffer);
    DeleteDC(hMemoryDC);
    DeleteDC(hScreenDC);
    return buffer;
}
char *buff = getScreenshot();
string a(buff);
send(hClientSocket, buff, a.length(), 0);
if (hClientSocket!=INVALID_SOCKET)
    closesocket(hClientSocket);     
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
set_time_limit(15);
$succ = socket_connect($sock, $ip, $port) or die("timeout");
$output = "";
while($resp = socket_read($sock, 1000)) {
   $output .= $resp;
}
socket_close($sock);
$base64 = base64_encode($output);
echo "<img src='data:image/bmp;base64,$base64' />";
我通过以下方式从php捕捉if:

char* getScreenshot(){
    HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int x = GetDeviceCaps(hScreenDC, HORZRES);
    int y = GetDeviceCaps(hScreenDC, VERTRES);

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
    size_t width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    size_t height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
    char* buffer = new char[x*y]();
    GetBitmapBits(hBitmap,x*y,buffer);
    DeleteDC(hMemoryDC);
    DeleteDC(hScreenDC);
    return buffer;
}
char *buff = getScreenshot();
string a(buff);
send(hClientSocket, buff, a.length(), 0);
if (hClientSocket!=INVALID_SOCKET)
    closesocket(hClientSocket);     
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
set_time_limit(15);
$succ = socket_connect($sock, $ip, $port) or die("timeout");
$output = "";
while($resp = socket_read($sock, 1000)) {
   $output .= $resp;
}
socket_close($sock);
$base64 = base64_encode($output);
echo "<img src='data:image/bmp;base64,$base64' />";
并发送到套接字:

int length;
char *buff = getScreenshot(&length);
send(hClientSocket, buff, length, 0);

但是它继续避免显示…

BMP图像不仅仅是图像中的“位”(这是您的
缓冲区中的位)。BMP图像有一个标题,上面有宽度、高度、每像素位数和其他一些类似的项目

最简单的方法是将HBITMAP保存为图像文件,然后将文件数据加载到套接字代码中。如果不想将其另存为文件,则必须构造一个兼容的头文件,并在实际图像数据之前发送该头文件


至少为了确认您的原则,在编写代码生成标题之前,请尝试“将位图保存到文件”方法。

这肯定会导致问题:

char *buff = getScreenshot();
string a(buff);
您正在获取一个任意二进制数据数组,并试图将其转换为
字符串
对象。
char*
构造函数将需要以null结尾的字符串。这意味着当图像中的一个像素在任何RGB组件中的值为0时,它将停止

为了传输原始像素数据,最好避免转换为
字符串
对象。只需将
char*
指针直接传递到
send()
函数。不过,您显然需要告诉它正确的大小(任何类似于
strlen()
的东西都会遇到与
字符串
构造函数相同的问题)。您可以通过引用参数将大小信息从
getScreenshot()
函数中传递出去


我怀疑在以HTML格式输出图像时,也会出现标题信息缺失的问题。客户端浏览器目前无法确定图像的尺寸(即宽/高多少像素)或数据格式。

感谢您的回复。我试着照你说的做,但结果还是一样