So im trying to send a HBITMAP over socket, and comming to some issues. I know that HBITMAP is a handle, a memory reference pointer to the image bytes. So what i did, was lookup on google how to convert it to a byte array, and therefore be able to send it:
void *pktdata;
std::vector<uint8_t> pixels;
uint32_t width;
uint32_t height;
uint16_t BitsPerPixel;
HBITMAPToPixels(texture, pixels, width, height, BitsPerPixel);
int pktsize = sizeof(PKT_Structure_s) + sizeof(std::vector<uint8_t>) + (sizeof(uint8_t) * pixels.size());
PKT_Structure_s n;
n.width = width;
n.height = height;
n.BitsPerPixel = BitsPerPixel;
n.DataSize = sizeof(std::vector<uint8_t>) + (sizeof(uint8_t) * pixels.size());
memcpy(&pktdata, &n, sizeof(n));
memcpy(&pktdata + sizeof(n), &pixels, n.DataSize);
p2pSendToHost(NULL, (DefaultPacket*)pktdata, pktsize);
delete[] pktdata;
return;
And this is the HBITMAPToPixels i got from another stackoverflor question:
void HBITMAPToPixels(HBITMAP BitmapHandle, std::vector<uint8_t> &Pixels, uint32_t &width, uint32_t &height, uint16_t &BitsPerPixel)
{
if (BitmapHandle == NULL)
{
throw std::logic_error("Null Pointer Exception. BitmapHandle is Null.");
}
Pixels.clear();
BITMAP Bmp = { 0 };
BITMAPINFO Info = { 0 };
HDC DC = CreateCompatibleDC(NULL);
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);
}
And this is crashing sometimes, and sometimes it actually sends the packet but the server then crashes. This is how the server handles the packet:
void Server::ProcessScreenShot(const void * packetdatadata, int packetsizesize)
{
PKT_Structure_sn;
std::vector<uint8_t> pixels;
int pktsize = sizeof(PKT_Structure_s) + sizeof(std::vector<uint8_t>) + (sizeof(uint8_t) * pixels.size());
memcpy(&n, packetdatadata, sizeof(n)); //Get Our Packet Struct
memcpy(&pixels, &packetdatadata + sizeof(n), n.DataSize); // Get Our Image in bytes
HBITMAP btmp = HBITMAPFromPixels(pixels, n.width, n.height, n.BitsPerPixel);
time_t t = time(0);
struct tm * now = localtime(&t);
char filename[MAX_PATH];
sprintf(filename, "SS.bmp");
HPALETTE hpal = NULL;
saveBitmap(filename, btmp, hpal);
return;
}
And last but not least, the other function i used from the question answer to get my HBITMAP back:
HBITMAP HBITMAPFromPixels(const std::vector<uint8_t> &Pixels, uint32_t width, uint32_t height, 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(NULL), &Info.bmiHeader, CBM_INIT, &Pixels[0], &Info, DIB_RGB_COLORS);
return Result;
}
And the save function is irrelevant, since ive tested it on a console app really quick and it works.
I think i might be doing wrong by memcpy as i got really confused while doing that, which is probs crashing.
Thanks
Aucun commentaire:
Enregistrer un commentaire