本文介绍了C ++如何通过套接字发送Hbitmap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的GetScreen函数如下:

void GetScreen(int clientSocket, const char *filename) {
         HDC hDC = NULL;
         int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
         int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
         HWND hDesktopWnd = GetDesktopWindow();
         HDC hDesktopDC = GetDC(hDesktopWnd);
         HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
         HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,
                                 nScreenWidth, nScreenHeight);
         SelectObject(hCaptureDC,hCaptureBitmap);
         BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
                hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
         SaveBitmap(clientSocket, "test.bmp",hCaptureBitmap); //here to save the captured image to disk
         **//here to send Hbitmap: send(clientSocket,?,?,Null);**

         ReleaseDC(hDesktopWnd,hDesktopDC);
         DeleteDC(hCaptureDC);
         DeleteObject(hCaptureBitmap);
}

现在,我想通过套接字发送HBITMAP而不保存位图.我已经用Google搜索,找到了GetDIBitsSetDIBits但我不知道该如何准确地使用它.有人能帮我吗?谢谢.

Now I want to send HBITMAP over socket without bitmap saving.I've Googled and have found GetDIBits and SetDIBitsbut I do not know how I can use it exactly. Can someone help me? Thank you.

现在,我尝试使用以下代码从HBITMAP获取BYTE:

now i tried to get BYTE from HBITMAP with this code:

BYTE* getPixArray(HBITMAP hBitmap)
        {
        HDC hdc,hdcMem;

        hdc = GetDC(NULL);
        hdcMem = CreateCompatibleDC(hdc);

        BITMAPINFO MyBMInfo = {0};
        MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
        // Get the BITMAPINFO structure from the bitmap
        if(0 == GetDIBits(hdcMem, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
        {
            cout<<"FAIL\n"<<endl;
        }

        // create the bitmap buffer
        BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];

        MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
        MyBMInfo.bmiHeader.biBitCount = 32;
        MyBMInfo.bmiHeader.biCompression = BI_RGB;
        MyBMInfo.bmiHeader.biHeight = (MyBMInfo.bmiHeader.biHeight < 0) ? (-MyBMInfo.bmiHeader.biHeight) : (MyBMInfo.bmiHeader.biHeight);

        // get the actual bitmap buffer
        if(0 == GetDIBits(hdc, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS))
        {
            cout<<"FAIL\n"<<endl;
        }

        return lpPixels;
    }

现在在套接字的另一端,我想从BYTE获取HBITMAP!?!请帮我.谢谢.

now in the other side of socket i want to get HBITMAP from BYTE!?!please help me. thx.

推荐答案

一旦您拥有HBITMAP,请致电HBITMAPToPixels.发送widthheightbitsperpixel.接下来发送像素.

Once you have an HBITMAP, call HBITMAPToPixels. Send the width, the height, and the bitsperpixel. Next send the pixels..

在套接字的另一端,读取width,读取height,读取bitsperpixel.然后创建一个大小为((width * Bmp.bmBitsPixel + 31) / 32) * 4 * height的缓冲区将那么多字节读取到缓冲区中,然后调用HBITMAPFromPixels

On the other end of the socket, read width, read height, read bitsperpixel.Then create a buffer of size: ((width * Bmp.bmBitsPixel + 31) / 32) * 4 * heightRead that many bytes into the buffer and call HBITMAPFromPixels

所讨论的功能在下面定义.

The functions discussed are defined below..

#include <iostream>
#include <stdexcept>
#include <vector>
#include <cstring>
#include <memory>
#include <windows.h>

std::unique_ptr<std::remove_pointer<HBITMAP>::type, std::function<void(HBITMAP)>> HBITMAPFromPixels(const std::vector<std::uint8_t> &Pixels, std::uint32_t width, std::uint32_t height, std::uint16_t BitsPerPixel)
{
    BITMAPINFO Info = {0};
    std::memset(&Info, 0, sizeof(BITMAPINFO));

    Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biWidth = width;
    Info.bmiHeader.biHeight = -height;
    Info.bmiHeader.biPlanes = 1;
    Info.bmiHeader.biBitCount = BitsPerPixel;
    Info.bmiHeader.biCompression = BI_RGB;
    Info.bmiHeader.biSizeImage = ((width * BitsPerPixel + 31) / 32) * 4 * height;

    HBITMAP Result = CreateDIBitmap(GetDC(nullptr), &Info.bmiHeader, CBM_INIT, &Pixels[0], &Info, DIB_RGB_COLORS);
    return std::unique_ptr<std::remove_pointer<HBITMAP>::type, std::function<void(HBITMAP)>>(Result, [&](HBITMAP hBmp){DeleteObject(hBmp);});
}

void HBITMAPToPixels(HBITMAP BitmapHandle, std::vector<std::uint8_t> &Pixels, std::uint32_t &width, std::uint32_t &height, std::uint16_t &BitsPerPixel)
{
    if (BitmapHandle == nullptr)
    {
        throw std::logic_error("Null Pointer Exception. BitmapHandle is Null.");
    }

    Pixels.clear();
    BITMAP Bmp = {0};
    BITMAPINFO Info = {0};
    HDC DC = CreateCompatibleDC(nullptr);
    std::memset(&Info, 0, sizeof(BITMAPINFO));
    HBITMAP OldBitmap = (HBITMAP)SelectObject(DC, BitmapHandle);
    GetObject(BitmapHandle, sizeof(Bmp), &Bmp);

    Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biWidth = width = Bmp.bmWidth;
    Info.bmiHeader.biHeight = height = Bmp.bmHeight;
    Info.bmiHeader.biPlanes = 1;
    Info.bmiHeader.biBitCount = BitsPerPixel = Bmp.bmBitsPixel;
    Info.bmiHeader.biCompression = BI_RGB;
    Info.bmiHeader.biSizeImage = ((width * Bmp.bmBitsPixel + 31) / 32) * 4 * height;

    Pixels.resize(Info.bmiHeader.biSizeImage);
    GetDIBits(DC, BitmapHandle, 0, height, &Pixels[0], &Info, DIB_RGB_COLORS);
    SelectObject(DC, OldBitmap);
    height = height < 0 ? -height : height;
    DeleteDC(DC);
}

这篇关于C ++如何通过套接字发送Hbitmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-17 07:01