MFC,C++ 截屏


以前本人用C#制作過一些小游戲的外掛,其中一步最重要的原理是截取電腦的屏幕,然后分析關鍵像素點的信息。現在用C++重用這些程序時,在截屏上遇到一些問題,現在終於解決了,貼出自己整理后的代碼。

分為win32代碼和MFC代碼,如下

 1 void Test_captrueScreenwin32()
 2 {
 3     HDC hDesktopDc=CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
 4     int width=GetDeviceCaps(hDesktopDc,HORZRES);
 5     int height=GetDeviceCaps(hDesktopDc,VERTRES);
 6 
 7     HBITMAP hMemBmp;
 8     HDC hMemDc;
 9     hMemBmp=  CreateCompatibleBitmap(hDesktopDc,width,height);
10     hMemDc=CreateCompatibleDC(hDesktopDc);
11     ::SelectObject(hMemDc,hMemBmp);
12 
13     BitBlt(hMemDc,0,0,width,height,hDesktopDc,0,0,SRCCOPY);  //一定得先復制到內存中去
14      
15     BITMAP bmp;
16     ::GetObject(hMemBmp,sizeof(bmp),&bmp);   //從HBITMAP 到BITMAP
17     
18     BITMAPINFOHEADER m_bihScreen;
19     ZeroMemory(&m_bihScreen, sizeof(BITMAPINFOHEADER));//位圖信息頭
20     m_bihScreen.biBitCount = bmp.bmBitsPixel;//每個像素字節大小
21     m_bihScreen.biCompression = BI_RGB;
22     m_bihScreen.biHeight = bmp.bmHeight;//高度
23     m_bihScreen.biPlanes = 1;
24     m_bihScreen.biSize = sizeof(BITMAPINFOHEADER);
25     m_bihScreen.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//圖像數據大小
26     m_bihScreen.biWidth = bmp.bmWidth;//寬度
27 
28     byte *m_pbmScreenData = new byte[bmp.bmWidthBytes * bmp.bmHeight];
29     GetDIBits(hMemDc,hMemBmp, 0, height, m_pbmScreenData,  
30         (LPBITMAPINFO) &m_bihScreen, DIB_RGB_COLORS);//獲取位圖數據  從BITMAP到內存數據
31 
32     TwoDimesionArray<RGBQUAD> colors(width,height);
33     for (int j=0;j<height;++j)
34     {
35         for (int i=0;i<width;++i)
36         {
37             byte *p=m_pbmScreenData+(height-1-j)*bmp.bmWidthBytes+i*4;
38             RGBQUAD c={int(*p),int(*(p+1)),int(*(p+2))};   //這里獲取每個位置上的像素
39             colors.SetValue(i,j,c);
40         }
41     }
42 
43     ImageIO writer;
44     writer.WriteBmp(colors,"D:\\z.bmp");
45 }
 1 void Test_captureScreenMFC()
 2 {
 3     CDC *pDesktopDC = CDC::FromHandle(::GetDC(NULL));//獲取當前整個屏幕DC
 4     int width = pDesktopDC->GetDeviceCaps(HORZRES);
 5     int height = pDesktopDC->GetDeviceCaps(VERTRES);
 6 
 7     CBitmap    memBmp;
 8     CDC memDC;
 9     memBmp.CreateCompatibleBitmap(pDesktopDC, width, height);
10     memDC.CreateCompatibleDC(pDesktopDC);
11     memDC.SelectObject(&memBmp);  //將memBitmap選入內存DC
12 
13     memDC.BitBlt(0, 0, width, height, pDesktopDC, 0, 0, SRCCOPY);//復制屏幕圖像到內存DC
14     
15     BITMAP bmp;
16     memBmp.GetBitmap(&bmp); //CBitmap到BITMAP
17 
18     BITMAPINFOHEADER m_bihScreen;  
19     ZeroMemory(&m_bihScreen, sizeof(BITMAPINFOHEADER));//位圖信息頭
20     m_bihScreen.biBitCount = bmp.bmBitsPixel;//每個像素字節大小
21     m_bihScreen.biCompression = BI_RGB;
22     m_bihScreen.biHeight = bmp.bmHeight;//高度
23     m_bihScreen.biPlanes = 1;
24     m_bihScreen.biSize = sizeof(BITMAPINFOHEADER);
25     m_bihScreen.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//圖像數據大小
26     m_bihScreen.biWidth = bmp.bmWidth;//寬度
27 
28     byte *m_pbmScreenData = new byte[bmp.bmWidthBytes * bmp.bmHeight];
29     GetDIBits(/*pDesktopDC->m_hDC*/memDC.m_hDC, (HBITMAP)memBmp.m_hObject, 0, height, m_pbmScreenData,  
30         (LPBITMAPINFO) &m_bihScreen, DIB_RGB_COLORS);//獲取位圖數據  從BITMAP到內存數據
31 
32     TwoDimesionArray<RGBQUAD> colors(width,height);
33     for (int j=0;j<height;++j)
34     {
35         for (int i=0;i<width;++i)
36         {
37             byte *p=m_pbmScreenData+(height-1-j)*bmp.bmWidthBytes+i*4;
38             RGBQUAD c={int(*p),int(*(p+1)),int(*(p+2))};
39             colors.SetValue(i,j,c);
40         }
41     }
42 
43     ImageIO writer;
44     writer.WriteBmp(colors,"D:\\z.bmp");
45 }
GetDIBits是DDB轉化為DIB的關鍵函數。
TwoDimesionArray<T>是自定義的模板類,封裝了二維數組的相關操作。
ImageIO 是保存圖片到文件的類。

通過這兩段代碼顯示了win32和MFC對應數據類型的不同


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM