【问题标题】:HBitmap byte array to phpHBitmap字节数组到php
【发布时间】:2013-11-19 22:28:46
【问题描述】:

我正在尝试以这种方式在我的控制台 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;
}

buffer 应该是包含 hbitmap 截图的字节数组。

然后我以这种方式通过套接字发送它:

char *buff = getScreenshot();
string a(buff);
send(hClientSocket, buff, a.length(), 0);
if (hClientSocket!=INVALID_SOCKET)
    closesocket(hClientSocket);     

我以这种方式从 php 中捕获 if:

$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' />";

我的问题是我无法使用上面写的方法显示图像。

可能是什么问题? 我哪里错了?

谢谢!

编辑

根据@Peter R. Bloomfield 所说,我将函数更改为:

char* getScreenshot(int* length){
   ...
   *length = x*y;
   ...
}

并发送到套接字:

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

但它继续避免显示...

【问题讨论】:

    标签: php c++ winapi base64


    【解决方案1】:

    BMP 图像不仅仅是图像中的“位”(这是您的buffer 中的内容)。 BMP 图像有一个标题,其中包含宽度、高度、每像素位数和其他一些此类项目。

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

    至少要确认您的原则,在编写代码以制作标题之前尝试“将位图保存到文件”方法。

    【讨论】:

      【解决方案2】:

      这势必会导致问题:

      char *buff = getScreenshot();
      string a(buff);
      

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

      为了传输原始像素数据,最好完全避免转换为string 对象。只需将char * 指针直接传递给send() 函数即可。你显然需要告诉它正确的大小(像strlen() 这样的任何东西都会与string 构造函数有同样的问题)。您可以通过参考参数将尺寸信息从getScreenshot() 函数中传递出去。

      我怀疑当您以 HTML 格式输出图像时,您还会遇到缺少标题信息的问题。客户端浏览器目前无法判断图像的尺寸(即宽/高多少像素)或数据格式。

      【讨论】:

      • 感谢您的回复。我试着照你说的做,但它继续给我同样的结果
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      相关资源
      最近更新 更多