vc 截取屏幕

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vc 截取屏幕相关的知识,希望对你有一定的参考价值。

本人需要实现以下功能
1.截取屏幕
2.将截取到的屏幕图像保存为jpg

现在的程序可以实现上述的功能,但是实现的手法并不好,先将屏幕的图像放入CBitmap,然后保存为BMP,然后用CImage载入BMP再保存为JPG

有没有办法直接将截取的图像放入CImage中,或者有没有什么办法将CBitmap中的图像不经过硬盘直接被CImage保存为JPG,如果CBitmap能直接保存为JPG更好
to hnjdbxf:
保存成BMP我早已实现
to 卩过眼云烟灬:
扯淡
to constmy:
该方法试过,一用就异常

诸位不要胡说,看我的代码
这是直接用CImage截屏,不需要CBitmap,也不用保存为BMP再转换

BOOL bFull=true;//是否截全屏,false则只截取当前活动的窗体
CImage image;
CWnd* pWnd;
CRect rect;
BOOL bStat;
if(bFull)
pWnd = CWnd::GetDesktopWindow();
else
pWnd = CWnd::GetActiveWindow();

ASSERT(pWnd);
if(pWnd == NULL)
return FALSE;

CWindowDC winDC(pWnd);
pWnd->GetWindowRect(&rect);

int nBPP = winDC.GetDeviceCaps(BITSPIXEL) * winDC.GetDeviceCaps(PLANES);
if(nBPP < 24) nBPP = 24;

bStat = image.Create(rect.Width(), rect.Height(), nBPP);
ASSERT(bStat);
if(!bStat)
return FALSE;

CImageDC imageDC(image);

::BitBlt(imageDC, 0, 0, rect.Width(), rect.Height(), winDC, 0, 0, SRCCOPY);

SYSTEMTIME sys;
GetLocalTime(&sys);
m_StaticTime.Format("%4d%02d%02d%02d%02d%02d",sys.wYear,sys.wMonth,sys.wDay,sys.wHour,sys.wMinute,sys.wSecond);

HRESULT hr = image.Save("img\\" + m_StaticTime + ".jpg");
参考技术A void CMainFrame::CapScr(CDC *pDC)//抓屏并存入临时文件

CBitmap m_bmp;
LPSTR lpData;
DWORD size;
BITMAPINFOHEADER bih;
BITMAPFILEHEADER bfh;
CBitmap bm;
CDC dc;
dc.CreateDC("DISPLAY",NULL,NULL,NULL);
int Width=GetSystemMetrics(SM_CXSCREEN);
int Height=GetSystemMetrics(SM_CYSCREEN);
bm.CreateCompatibleBitmap(&dc,Width,Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap*pOld=tdc.SelectObject(&bm);
tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
tdc.SelectObject(pOld);
BITMAP btm;
bm.GetBitmap(&btm);
size=btm.bmWidthBytes*btm.bmHeight;
lpData=(LPSTR)::GlobalAlloc(GPTR,size);
/////////////////////////////////////////////
bih.biBitCount=btm.bmBitsPixel;
bih.biClrImportant=0;
bih.biClrUsed=0;
bih.biCompression=0;
bih.biHeight=btm.bmHeight;
bih.biPlanes=1;
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biSizeImage=size;
bih.biWidth=btm.bmWidth;
bih.biXPelsPerMeter=0;
bih.biYPelsPerMeter=0;
GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
//////////////////////////////////////////////
CBitmap tbitmap;
tbitmap.CreateBitmapIndirect(&btm);
CDC m_memDC;
m_memDC.CreateCompatibleDC(pDC);
SetDIBits(m_memDC.m_hDC,tbitmap,0,btm.bmHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);

bfh.bfReserved1=bfh.bfReserved2=0;
bfh.bfType=((WORD)('M'<<8)|'B');
bfh.bfSize=54+size;
bfh.bfOffBits=54;

CFile bf;
if(bf.Open("C:\\temp.bmp",CFile::modeCreate|CFile::modeWrite))

bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));
bf.WriteHuge(lpData,size);
bf.Close();

::GlobalFree(lpData);//0121
参考技术B 游戏里按SCROLL LOCK 参考技术C 用CImage::Attach();它接受一个HBITMAP,用CBitmap的 HBITMAP运算符转换,代码如下:

CBitmap bitmap;
CImage imgTemp;
imgTemp.Attach(bitmap.operator HBITMAP());
imgTemp.Save(strFilePath);

楼主缺少的应该是bitmap.operator HBITMAP()这一步.

如何截取某一窗口内的图像 VC

如何截取某一窗口内的图像,类似游戏中截图,按下键盘中按键,只截取该程序窗口内的图象。

参考技术A 取得client句柄->取得其DC->用CDC的函数将该DC的内容blt到bmp中。
总之取得窗口的CDC是肯定要的,能成功取得了以后你可以用CDC的函数按照你的需要来做
参考技术B 这个很简单呀,只要你了解位图的结构,然后把屏幕的区域象素保存到位图里就可以啦。 参考技术C 你用原生的api BOOL GetClientRect( HWND hWnd,LPRECT lpRect); 不用MFC的试试看呢?用 GetForegroundWindow 获取前端窗口句柄 参考技术D void GetWindowClientImg(HWND hwnd, HDC hdc)

RECT rect;
GetClientRect(hwnd, &rect);
HDC whdc = GetDC(hwnd);
BitBlt(hdc, 0, 0, rect.right, rect.bottom, whdc, 0, 0, SRCCOPY);
ReleaseDC(hwnd, whdc);
本回答被提问者采纳

以上是关于vc 截取屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何截取某一窗口内的图像 VC

Java应用程序实现屏幕的"拍照"

VC++优化截屏如何实现

VC++截图编程:如何能完整地截图?要求是能够截取层级窗口的方法。

iOS - 以编程方式截取跳板(主屏幕)的屏幕截图

如何在颤动中截取屏幕之外的小部件屏幕截图?