我的程序的目的是每1/16秒進行一次屏幕截圖,並通過套接字發送給遠程服務器。我可以將bmp內存數據轉換成更小的png內存數據嗎?
目前這個程序可以使用BMP格式的屏幕截圖,但是BMP格式的數據有太多的字節要發送,這顯然會拖慢send和recv過程。
我的想法是:如果我可以將BMP轉換成PNG,並在發送之前壓縮它,也許程序可以更順暢地工作。
這裏是我的代碼,從gh0st項目
LPVOID m_lpvFullBits = NULL;
HDC m_hFullDC, m_hFullMemDC;
LPBITMAPINFO m_lpbmi_full;
m_hFullDC = GetDC(NULL);
int m_nFullWidth = ::GetSystemMetrics(SM_CXSCREEN);
int m_nFullHeight = ::GetSystemMetrics(SM_CYSCREEN);
m_hFullMemDC = ::CreateCompatibleDC(m_hFullDC);
m_lpbmi_full = (BITMAPINFO *) new BYTE[40];
BITMAPINFOHEADER *lpbmih = &(m_lpbmi_full ->bmiHeader);
lpbmih->biSize = sizeof(BITMAPINFOHEADER);
lpbmih->biWidth = m_nFullWidth ;
lpbmih->biHeight = m_nFullHeight ;
lpbmih->biPlanes = 1;
lpbmih->biBitCount = 32; // 32 bit per pixel
lpbmih->biCompression = BI_RGB;
lpbmih->biXPelsPerMeter = 0;
lpbmih->biYPelsPerMeter = 0;
lpbmih->biClrUsed = 0;
lpbmih->biClrImportant = 0;
lpbmih->biSizeImage = (((lpbmih->biWidth * lpbmih->biBitCount + 31) & ~31) >> 3) * lpbmih->biHeight;
HBITMAP m_hFullBitmap = ::CreateDIBSection(m_hFullDC, m_lpbmi_full, DIB_RGB_COLORS, &m_lpvFullBits, NULL, NULL);
::SelectObject(m_hFullMemDC, m_hFullBitmap);
::BitBlt(m_hFullMemDC, 0, 0, m_nFullWidth, m_nFullHeight, m_hFullDC, 0, 0, SRCCOPY);
選擇,直到這個說法:
::BitBlt(m_hFullMemDC, 0, 0, m_nFullWidth, m_nFullHeight, m_hFullDC, 0, 0, SRCCOPY);
BMP像素的數據被保存在地址從m_lpvFullBits開始,對不對?
現在我想知道的是,我可以使用當前已知的信息,如寬度,高度,BMP像素數據..,重建一個新的PNG格式的內存數據比目前的BMP數據小得多,並通過套接字發送新的PNG格式數據到遠程服務器?
感謝您的任何幫助
是的,這是可能的。您需要使用[Windows圖像組件](https://msdn.microsoft.com/en-us/library/windows/desktop/ee719902.aspx)中的PNG編碼器。它在'IStream'接口上工作,所以你可以傳遞一個內存流實現。 – IInspectable
_將BMP轉換爲PNG,並在發送之前對其進行壓縮...轉換爲PNG後不需要ZIP,因爲PNG格式已經「拉」了數據,並且它比ZIP更高效。 – zett42
gdiplus會不會更容易使用來保存到PNG?或者它只能將PNG保存到磁盤而不是內存? –