最近在做一个远程监控程序,被控方截图发送到监控方然后显示,但是在显示时,发现图片左边一部分被切割到了右边,这是怎么产生的?
已经将截图文件和接收的文件对比过了,图片文件没出错,感觉应该错在显示上,我是用的BitBlt函数显示的,不知道出了什么问题。
显示功能的代码如下
BOOL CMFCApplication4Dlg::onEraseBkgnd(CDC* pDC)
{
CDC DCmem;
DCmem.CreateCompatibleDC(pDC);
CBitmap bitmap;
bitmap.m_hObject = GetBitmapFromData();
CRect rect;
GetClientRect(&rect);
CBitmap *pOldBit = DCmem.SelectObject(&bitmap);
BITMAP bmpinfo;
bitmap.GetBitmap(&bmpinfo);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &DCmem, 0, 0, SRCCOPY);
/*pDC->SetStretchBltMode(STRETCH_HALFTONE);
pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &DCmem, 0, 0, bmpinfo.bmWidth, bmpinfo.bmHeight,SRCCOPY);*/
DCmem.DeleteDC();
bitmap.DeleteObject();
//ReleaseDC(&DCmem);
return TRUE;
}
这段代码看不出来什么问题
也许是网络接收数据后缓冲区的读写问题
数据整体右移,说明你的接受数据生产BMP时产生了错误。。看看这部分代码!!
发现图片左边一部分被切割到了右边
我也有这个问题,应该是保存的问题。后面我去MSDN上找了新的代码,解决了。
https://docs.microsoft.com/en-us/windows/win32/gdi/storing-an-image?redirectedfrom=MSDN
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp) {
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
//Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
exit(-1);
// Convert the color format to a count of bits.
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
if (cClrBits < 24)
pbmi = (PBITMAPINFO)LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (static_cast<unsigned long long>(1) << cClrBits));
else
pbmi = (PBITMAPINFO)LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1 << cClrBits);
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31) & ~31) / 8
* pbmi->bmiHeader.biHeight;
pbmi->bmiHeader.biClrImportant = 0;
return pbmi;
}
BOOL _CreateBMPFile(LPCWSTR pszFile, HBITMAP hBMP)
{
HDC hDC;
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE* hp; // byte pointer
DWORD dwTmp;
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
PBITMAPINFO pbi = CreateBitmapInfoStruct(hBMP);
pbih = (PBITMAPINFOHEADER)pbi;
lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits)
return FALSE;
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD)pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
return FALSE;
}
// Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD)0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL);
if (hf == INVALID_HANDLE_VALUE)
return FALSE;
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD);
// Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID)&hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD)&dwTmp, NULL))
{
return FALSE;
}
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID)pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof(RGBQUAD),
(LPDWORD)&dwTmp, (NULL)))
return FALSE;
// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR)hp, (int)cb, (LPDWORD)&dwTmp, NULL))
return FALSE;
// Close the .BMP file.
if (!CloseHandle(hf))
return FALSE;
// Free memory.
GlobalFree((HGLOBAL)lpBits);
}
HBITMAP _GetCaptureBmp()
{
HDC hDC;
HDC MemDC;
BYTE* Data;
HBITMAP hBmp;
BITMAPINFO bi;
memset(&bi, 0, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFO);
bi.bmiHeader.biWidth = GetSystemMetrics(SM_CXSCREEN);
bi.bmiHeader.biHeight = GetSystemMetrics(SM_CYSCREEN);
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
hDC = GetDC(NULL);
MemDC = CreateCompatibleDC(hDC);
hBmp = CreateDIBSection(MemDC, &bi, DIB_RGB_COLORS, (void**)&Data, NULL, 0);
SelectObject(MemDC, hBmp);
BitBlt(MemDC, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, hDC, 0, 0, SRCCOPY);
ReleaseDC(NULL, hDC);
DeleteDC(MemDC);
return hBmp;
}