EVC截图存储,连续存储的话,内存会不够 怎么改
[复制链接]
/********************************************************
CopyScreenToBitmap 得到hdc中指定区域的图像句柄
*********************************************************/
HBITMAP CJietuDlg::CopyScreenToBitmap(int &nWidth,int &nHeight)
{
HDC hScrDC;
HDC hMemDC;
//屏幕和内存设备描述表
HBITMAP hBitmap;
HBITMAP hOldBitmap;
//为屏幕创建设备描述表
hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
nWidth = 800;
nHeight = 480;
//创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
//把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap);
//把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, 0, 0, SRCCOPY);
//得到屏幕位图的句柄
hBitmap=(HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除
DeleteObject(hOldBitmap);
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// DeleteObject(hBitmap);
// 返回位图句柄
return hBitmap;
}
/*****************************************************
GettingBits 通过图像句柄得到图像数据,源句柄未删除
*****************************************************/
LPSTR CJietuDlg::GettingBits(HBITMAP hSourceBitmap)
{
LPSTR lpDIB=NULL;
//1.Initialize source bitmap.For example load from resources.
//HBITMAP hSourceBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
//2.Getting bimap size.
BITMAP bm;
GetObject(hSourceBitmap,sizeof(BITMAP),&bm);
lpDIB = (LPSTR)LocalAlloc(LPTR,bm.bmHeight*WIDTHBYTES(bm.bmWidth*24)+40);
if(lpDIB==NULL)
{
return NULL;
}
//3.Creating new bitmap and receive pointer to it's bits.
HBITMAP hTargetBitmap = NULL;
void *pBuffer;
//3.1 Initilize DIBINFO structure
DIBINFO dibInfo;
dibInfo.bmiHeader.biBitCount = 24;
dibInfo.bmiHeader.biClrImportant = 0;
dibInfo.bmiHeader.biClrUsed = 0;
dibInfo.bmiHeader.biCompression = 0;
dibInfo.bmiHeader.biHeight = bm.bmHeight;
dibInfo.bmiHeader.biPlanes = 1;
dibInfo.bmiHeader.biSize = 40;
dibInfo.bmiHeader.biSizeImage = WIDTHBYTES(bm.bmWidth*24)*bm.bmHeight;
dibInfo.bmiHeader.biWidth = bm.bmWidth;
dibInfo.bmiHeader.biXPelsPerMeter = 3780;
dibInfo.bmiHeader.biYPelsPerMeter = 3780;
dibInfo.bmiColors[0].rgbBlue = 0;
dibInfo.bmiColors[0].rgbGreen = 0;
dibInfo.bmiColors[0].rgbRed = 0;
dibInfo.bmiColors[0].rgbReserved = 0;
//3.2 Create bitmap and receive pointer to points into pBuffer
HDC hDC = ::GetDC(NULL);
ASSERT(hDC);
hTargetBitmap = CreateDIBSection(
hDC,
(const BITMAPINFO*)dibInfo,
DIB_RGB_COLORS,
(void**)&pBuffer,
NULL,
0);
::ReleaseDC(NULL,hDC);
//4.Copy source bitmap into the target bitmap.
//4.1Create 2 device contexts
HDC memDc;
memDc=CreateCompatibleDC(NULL);
ASSERT(memDc!=NULL);
HDC targetDc;
targetDc=CreateCompatibleDC(NULL);
ASSERT(targetDc!=NULL);
//4.2 Select source bitmap into one DC,target into another
HBITMAP hOldBitmap1 = (HBITMAP)::SelectObject(memDc, hSourceBitmap);
HBITMAP hOldBitmap2 = (HBITMAP)::SelectObject(targetDc, hTargetBitmap);
//4.3 Copy source bitmap into the target one
BitBlt(targetDc,0, 0, bm.bmWidth, bm.bmHeight, memDc, 0, 0, SRCCOPY);
//4.4 Restore device contexts
::SelectObject(memDc, hOldBitmap1);
::SelectObject(targetDc, hOldBitmap2);
DeleteDC(memDc);
DeleteDC(targetDc);
//Here we can bitmap bits:pBuffer.Note:
// 1.pBuffer contains 3 bytes per point
// 2.Lines ane from the bottom to the top!
// 3.Points in the line are from the left to the right
// 4.Bytes in one point are BGR(blue,green,red)not RGB
// 5.Don't delete pBuffer,it will be automatically deleted
// when delete hTargetBitmap
LPSTR lptmp=lpDIB;
CopyMemory(lptmp,&dibInfo.bmiHeader,40);
lptmp+=40;
CopyMemory(lptmp,pBuffer,dibInfo.bmiHeader.biSizeImage);
DeleteObject(hSourceBitmap);
DeleteObject(hTargetBitmap);
return lpDIB;
}
/******************************************************
SaveDIBToFile 保存DIB到文件 szFileName 文件全名
******************************************************/
BOOL CJietuDlg::SaveDIBToFile(LPSTR hDib,LPCTSTR szFileName)
{
HANDLE ghFile=NULL;
BOOL bResult=FALSE;
//Bitmap文件头
BITMAPFILEHEADER bmfHdr;
//指向BITMAPINFOHEADER的指针
LPBITMAPINFOHEADER lpBI=NULL;
// DIB大小
DWORD dwDIBSize=0;
DWORD dwBytes=0;
if (hDib == NULL)
{
return FALSE;
}
// 读取BITMAPINFO结构,并锁定
lpBI=(LPBITMAPINFOHEADER)hDib;
if (lpBI == NULL)
{
return FALSE;
}
// 判断是否是WIN3.0 DIB
if (!IS_WIN30_DIB(lpBI))
{
// 返回FALSE
return FALSE;
}
// 文件类型"BM"
bmfHdr.bfType = DIB_HEADER_MARKER;
// 文件头大小+颜色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
dwDIBSize = *(LPDWORD)lpBI + CJietuDlg::PaletteSize((LPSTR)lpBI);
// 计算图像大小
// 象素的大小
DWORD dwBmBitsSize;
// 大小为Width * Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
// 计算出DIB真正的大小
dwDIBSize += dwBmBitsSize;
// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
// 两个保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + PaletteSize((LPSTR)lpBI);
if(!DiskFree())
{
DeleteDirectory();
}
CString filename = getCurrentTime();
//打开文件
ghFile=CreateFile(TEXT("\\Storage Card\\"+filename+".bmp"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (ghFile==INVALID_HANDLE_VALUE)
{
NKDbgPrintfW(_T("save dib to file fail. \r\n"));
return FALSE;
}
//写文件头
bResult=WriteFile(ghFile,(LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER),&dwBytes,NULL);
ASSERT(bResult!=FALSE);
// 写DIB头和象素
bResult=WriteFile(ghFile,(LPSTR)lpBI,dwDIBSize,&dwBytes,NULL);
ASSERT(bResult!=FALSE);
CloseHandle(ghFile);
// 返回TRUE
return TRUE;
}
void CJietuDlg::OnBTNjieping()
{
// TODO: Add your control notification handler code here
char * a = "\\Storage Card\\save.bmp";
LPCTSTR qa=(LPCTSTR)(LPTSTR)a;
int nWidth,nHeight;
HBITMAP hbi = CJietuDlg::CopyScreenToBitmap(nWidth,nHeight);
LPSTR bits = CJietuDlg::GettingBits(hbi);
CJietuDlg::SaveDIBToFile(bits,qa);
DeleteObject(hbi);
bits=NULL;
}