实现windows下屏幕指定区域截图功能

  1 #ifndef AZ_PRINTSCREEN_H
  2 #define AZ_PRINTSCREEN_H
  3 
  4 #define WIN32API __declspec(dllexport)
  5 
  6 /***********************************************************************************************
  7 *函数名 : AZ_PRINTSCREEN_GetScreenRGB
  8 *函数功能描述 : 获取屏幕指定位置图像为RGB数据
  9 *函数参数 : (I)nx-开始位置x
 10 *           (I)ny-开始位置y
 11 *           (I)nWidth-宽度
 12 *           (I)nHeight-高度
 13 *           (O)pRGBBuf-得到的RGB数据
 14 *           (O)nLen-RGB数据长度
 15 *           (I)lShowOSD-是否显示OSD
 16 *函数返回值 : true-执行成功,false-执行失败
 17 *作者 : Ark Zhang
 18 *函数创建日期 : 2012.11.28
 19 *函数修改日期 : 
 20 *修改人 :
 21 *修改原因 :  
 22 *版本 : 1.0
 23 *历史版本 : 无
 24 ***********************************************************************************************/
 25 WIN32API bool AZ_PRINTSCREEN_GetScreenRGB(long nx, long ny, long nWidth, long nHeight, 
 26                                           char *pRGBBuf, long *nLen, long lShowOSD = 0);
 27 
 28 /***********************************************************************************************
 29 *函数名 : AZ_PRINTSCREEN_GetFullScreenRGB
 30 *函数功能描述 : 获取全屏幕图像为RGB数据
 31 *函数参数 : (O)pRGBBuf-得到的RGB数据
 32 *           (O)nLen-RGB数据长度
 33 *           (O)nWidth-宽度
 34 *           (O)nHeight-高度
 35 *           (I)lShowOSD-是否显示OSD
 36 *函数返回值 : true-执行成功,false-执行失败
 37 *作者 : Ark Zhang
 38 *函数创建日期 : 2012.11.28
 39 *函数修改日期 : 
 40 *修改人 :
 41 *修改原因 :  
 42 *版本 : 1.0
 43 *历史版本 : 无
 44 ***********************************************************************************************/
 45 WIN32API bool AZ_PRINTSCREEN_GetFullScreenRGB(char *pRGBBuf, long *nLen, long *nWidth, 
 46                                               long *nHeight, long lShowOSD = 0);
 47 
 48 /***********************************************************************************************
 49 *函数名 : AZ_PRINTSCREEN_SaveRGBToFile
 50 *函数功能描述 : 保存RGB数据为文件
 51 *函数参数 : (I)pFileName-文件名
 52 *           (I)pRGBBuf-RGB数据
 53 *           (I)nLen-RGB数据长度
 54 *           (I)nWidth-图像宽度
 55 *           (I)nHeight-图像高度
 56 *函数返回值 : true-执行成功,false-执行失败
 57 *作者 : Ark Zhang
 58 *函数创建日期 : 2012.11.28
 59 *函数修改日期 : 
 60 *修改人 :
 61 *修改原因 :  
 62 *版本 : 1.0
 63 *历史版本 : 无
 64 ***********************************************************************************************/
 65 WIN32API bool AZ_PRINTSCREEN_SaveRGBToFile(const char *pFileName, const char *pRGBBuf, 
 66                                            long nLen, long nWidth, long nHeight);
 67 
 68 /***********************************************************************************************
 69 *函数名 : AZ_PRINTSCREEN_SaveScreenToFile
 70 *函数功能描述 : 保存屏幕指定位置为文件
 71 *函数参数 : (I)pFileName-文件名
 72 *           (I)nx-开始位置x
 73 *           (I)ny-开始位置y
 74 *           (I)nWidth-宽度
 75 *           (I)nHeight-高度
 76 *函数返回值 : true-执行成功,false-执行失败
 77 *作者 : Ark Zhang
 78 *函数创建日期 : 2012.11.28
 79 *函数修改日期 : 
 80 *修改人 :
 81 *修改原因 :  
 82 *版本 : 1.0
 83 *历史版本 : 无
 84 ***********************************************************************************************/
 85 WIN32API bool AZ_PRINTSCREEN_SaveScreenToFile(const char *pFileName, long nx, long ny, 
 86                                               long nWidth, long nHeight);
 87 
 88 /***********************************************************************************************
 89 *函数名 : AZ_PRINTSCREEN_SaveFullScreenToFile
 90 *函数功能描述 : 保存全屏为文件
 91 *函数参数 : (I)pFileName-文件名
 92 *函数返回值 : true-执行成功,false-执行失败
 93 *作者 : Ark Zhang
 94 *函数创建日期 : 2012.11.28
 95 *函数修改日期 : 
 96 *修改人 :
 97 *修改原因 :  
 98 *版本 : 1.0
 99 *历史版本 : 无
100 ***********************************************************************************************/
101 WIN32API bool AZ_PRINTSCREEN_SaveFullScreenToFile(const char *pFileName);
102 
103 /***********************************************************************************************
104 *函数名 : AZ_PRINTSCREEN_SetRGBBitsPixel
105 *函数功能描述 : 设置RGB数据位宽,24、32可选
106 *函数参数 : (I)nbits-位宽
107 *函数返回值 : true-执行成功,false-执行失败
108 *作者 : Ark Zhang
109 *函数创建日期 : 2012.11.28
110 *函数修改日期 : 
111 *修改人 :
112 *修改原因 :  
113 *版本 : 1.0
114 *历史版本 : 无
115 ***********************************************************************************************/
116 WIN32API bool AZ_PRINTSCREEN_SetRGBBitsPixel(long nbits);
117 
118 
119 #endif
  1 #include "stdafx.h"
  2 #include "libprintscreen.h"
  3 
  4 #define             OSD_COLOR               RGB(255, 0, 0)
  5 
  6 #ifdef WIN32
  7 #define _TRACE TRACE
  8 #else
  9 #define _TRACE
 10 #endif
 11 
 12 #ifndef WIN32
 13 typedef struct tagBITMAPINFO
 14 {
 15     BITMAPINFOHEADER bmiHeader;
 16     RGBQUAD bmiColors[1]; //颜色表
 17 }BITMAPINFO;
 18 
 19 typedef struct tagBITMAPFILEHEADER {
 20     int16 bfType;
 21     int32 bfSize;
 22     int16 bfReserved1;
 23     int16 bfReserved2;
 24     int32 bfOffBits;
 25 } BITMAPFILEHEADER;
 26 
 27 typedef struct tagBITMAPINFOHEADER
 28 {
 29     int32 biSize;
 30     int32 biWidth;
 31     int32 biHeight;
 32     int16 biPlanes;
 33     int16 biBitCount;
 34     char biCompression[4];
 35     int32 biSizeImage;
 36     int32 biXPelsPerMeter;
 37     int32 biYPelsPerMeter;
 38     int32 biClrUsed;
 39     int32 biClrImportant;
 40 }BITMAPINFOHEADER;
 41 
 42 typedef struct tagRGBQUAD {
 43     BYTE    rgbBlue;
 44     BYTE    rgbGreen;
 45     BYTE    rgbRed;
 46     BYTE    rgbReserved;
 47 } RGBQUAD;
 48 #endif
 49 
 50 long m_nRGBBitsPixel = 24;
 51 bool AZ_PRINTSCREEN_ShowOSD(HDC hdc, long lPicWidth, long lPicHeight);
 52 
 53 /***********************************************************************************************
 54 *函数名 : AZ_PRINTSCREEN_GetScreenRGB
 55 *函数功能描述 : 获取屏幕指定位置图像为RGB数据
 56 *函数参数 : (I)nx-开始位置x
 57 *           (I)ny-开始位置y
 58 *           (I)nWidth-宽度
 59 *           (I)nHeight-高度
 60 *           (O)pRGBBuf-得到的RGB数据
 61 *           (O)nLen-RGB数据长度
 62 *           (I)lShowOSD-是否显示OSD
 63 *函数返回值 : true-执行成功,false-执行失败
 64 *作者 : Ark Zhang
 65 *函数创建日期 : 2012.11.28
 66 *函数修改日期 : 
 67 *修改人 :
 68 *修改原因 :  
 69 *版本 : 1.0
 70 *历史版本 : 无
 71 ***********************************************************************************************/
 72 WIN32API bool AZ_PRINTSCREEN_GetScreenRGB(long nx, long ny, long nWidth, long nHeight, 
 73                                           char *pRGBBuf, long *nLen, long lShowOSD)
 74 {
 75 #ifdef WIN32
 76     //获取bitmap
 77     HWND hWnd = ::GetDesktopWindow();
 78     HDC hdcSrc = ::GetDC(hWnd);
 79     HDC hdcMem = ::CreateCompatibleDC(hdcSrc);
 80     HBITMAP hBitmap = ::CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
 81     HGDIOBJ hOldbmp = ::SelectObject(hdcMem, hBitmap);
 82     ::BitBlt(hdcMem, 0, 0, nWidth, nHeight, hdcSrc, nx, ny, SRCCOPY);
 83     //显示OSD
 84     if (lShowOSD)
 85     {
 86         AZ_PRINTSCREEN_ShowOSD(hdcMem, nWidth, nHeight);
 87     }
 88     ::SelectObject(hdcMem, hOldbmp);
 89     ::DeleteObject(hdcMem);
 90     ::ReleaseDC(hWnd, hdcSrc);
 91 
 92     //从bitmap提取RGB数据
 93     if (hBitmap!= NULL)
 94     {
 95         CBitmap *bitmap = CBitmap::FromHandle(hBitmap);
 96         BITMAP bmp;
 97         bitmap->GetBitmap(&bmp);
 98         long bitmapSize = bmp.bmWidthBytes*bmp.bmWidthBytes;
 99         if (pRGBBuf==NULL)
100         {
101             return false;
102         }
103         bitmap->GetBitmapBits(bitmapSize, pRGBBuf);
104         bitmap->DeleteObject();
105         if (32 != m_nRGBBitsPixel)
106         {
107             //32位转24位
108             for (long nCount = 0; nCount < nWidth*nHeight*4;)
109             {
110                 memmove(&pRGBBuf[nCount/4*3], &pRGBBuf[nCount], 3);
111                 nCount += 4;
112             }
113         }
114         *nLen = nWidth*nHeight*m_nRGBBitsPixel/8;
115     }
116 
117 #if 0
118     //把图像数据倒置
119     long n = m_nRGBBitsPixel/8;
120     char tmp[2048*4];
121     for(long i = 0; i < nHeight/2; i++) 
122     { 
123         memcpy(tmp, &(pRGBBuf[nWidth*i*n]), nWidth*n); 
124         memcpy(&(pRGBBuf[nWidth*i*n]), &(pRGBBuf[nWidth*(nHeight-1-i)*n]), nWidth*n); 
125         memcpy(&(pRGBBuf[nWidth*(nHeight-1-i)*n]), tmp, nWidth*n); 
126     }
127 #endif
128 
129     return true;
130 #endif
131 
132     return true;
133 }
134 
135 /***********************************************************************************************
136 *函数名 : AZ_PRINTSCREEN_GetFullScreenRGB
137 *函数功能描述 : 获取全屏幕图像为RGB数据
138 *函数参数 : (O)pRGBBuf-得到的RGB数据
139 *           (O)nLen-RGB数据长度
140 *           (O)nWidth-宽度
141 *           (O)nHeight-高度
142 *           (I)lShowOSD-是否显示OSD
143 *函数返回值 : true-执行成功,false-执行失败
144 *作者 : Ark Zhang
145 *函数创建日期 : 2012.11.28
146 *函数修改日期 : 
147 *修改人 :
148 *修改原因 :  
149 *版本 : 1.0
150 *历史版本 : 无
151 ***********************************************************************************************/
152 WIN32API bool AZ_PRINTSCREEN_GetFullScreenRGB(char *pRGBBuf, long *nLen, long *nWidth, 
153                                               long *nHeight, long lShowOSD)
154 {
155 #ifdef WIN32
156     *nWidth = GetSystemMetrics(SM_CXSCREEN)+2;//全屏
157     *nHeight = GetSystemMetrics(SM_CYSCREEN);
158     //     *nWidth = GetSystemMetrics(SM_CXFULLSCREEN);//没有任务栏
159     //     *nHeight = GetSystemMetrics(SM_CYFULLSCREEN);
160     return AZ_PRINTSCREEN_GetScreenRGB(0, 0, *nWidth, *nHeight, pRGBBuf, nLen, lShowOSD);
161 #endif
162     return true;
163 }
164 
165 /***********************************************************************************************
166 *函数名 : AZ_PRINTSCREEN_SaveRGBToFile
167 *函数功能描述 : 保存RGB数据为文件
168 *函数参数 : (I)pFileName-文件名
169 *           (I)pRGBBuf-RGB数据
170 *           (I)nLen-RGB数据长度
171 *           (I)nWidth-图像宽度
172 *           (I)nHeight-图像高度
173 *函数返回值 : true-执行成功,false-执行失败
174 *作者 : Ark Zhang
175 *函数创建日期 : 2012.11.28
176 *函数修改日期 : 
177 *修改人 :
178 *修改原因 :  
179 *版本 : 1.0
180 *历史版本 : 无
181 ***********************************************************************************************/
182 WIN32API bool AZ_PRINTSCREEN_SaveRGBToFile(const char *pFileName, const char *pRGBBuf, 
183                                            long nLen, long nWidth, long nHeight)
184 {
185     FILE *file = fopen(pFileName, "wb+");
186     if (NULL == file)
187     {
188         _TRACE("open file failed, file name is:%s\n", pFileName);
189         return false;
190     }
191     //写文件头   
192     BITMAPFILEHEADER fileheader;  
193     ZeroMemory(&fileheader, sizeof(BITMAPFILEHEADER)); 
194     memcpy((char *)&fileheader.bfType, "BM", 2);
195     fileheader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nWidth*nHeight*m_nRGBBitsPixel/8;  
196     fileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
197     if (sizeof(BITMAPFILEHEADER) != fwrite((char *)&fileheader, sizeof(char), sizeof(BITMAPFILEHEADER), file))
198     {
199         _TRACE("write file error, file name is:%s\n", pFileName);
200         return false;
201     }
202     //写位图格式   
203     BITMAPINFOHEADER infoHeader;  
204     ZeroMemory(&infoHeader, sizeof(BITMAPINFOHEADER));  
205     infoHeader.biSize = sizeof(BITMAPINFOHEADER);  
206     infoHeader.biSizeImage = nWidth*nHeight*m_nRGBBitsPixel/8;  
207     infoHeader.biWidth = nWidth;  
208     infoHeader.biHeight = nHeight;  
209     infoHeader.biBitCount = m_nRGBBitsPixel; 
210     if (sizeof(BITMAPINFOHEADER) != fwrite((char *)&infoHeader, sizeof(char), sizeof(BITMAPINFOHEADER), file))
211     {
212         _TRACE("write file error, file name is:%s\n", pFileName);
213         return false;
214     }
215     //写位图数据  
216     if (nWidth*nHeight*m_nRGBBitsPixel/8 != fwrite(pRGBBuf, sizeof(char), nWidth*nHeight*m_nRGBBitsPixel/8, file))
217     {
218         _TRACE("write file error, file name is:%s\n", pFileName);
219         return false;
220     }
221     fclose(file);
222     return true;
223 }
224 
225 /***********************************************************************************************
226 *函数名 : AZ_PRINTSCREEN_SaveScreenToFile
227 *函数功能描述 : 保存屏幕指定位置为文件
228 *函数参数 : (I)pFileName-文件名
229 *           (I)nx-开始位置x
230 *           (I)ny-开始位置y
231 *           (I)nWidth-宽度
232 *           (I)nHeight-高度
233 *函数返回值 : true-执行成功,false-执行失败
234 *作者 : Ark Zhang
235 *函数创建日期 : 2012.11.28
236 *函数修改日期 : 
237 *修改人 :
238 *修改原因 :  
239 *版本 : 1.0
240 *历史版本 : 无
241 ***********************************************************************************************/
242 WIN32API bool AZ_PRINTSCREEN_SaveScreenToFile(const char *pFileName, long nx, long ny, 
243                                               long nWidth, long nHeight)
244 {
245     char *pRGBBuf = new char[nWidth*nHeight*4];
246     long nLen = 0;
247     if (!AZ_PRINTSCREEN_GetScreenRGB(nx, ny, nWidth, nHeight, pRGBBuf, &nLen))
248     {
249         _TRACE("get screen RGB failed\n");
250     }
251     AZ_PRINTSCREEN_SaveRGBToFile(pFileName, pRGBBuf, nLen, nWidth, nHeight);
252     delete []pRGBBuf;
253     return true;
254 }
255 
256 /***********************************************************************************************
257 *函数名 : AZ_PRINTSCREEN_SaveFullScreenToFile
258 *函数功能描述 : 保存全屏为文件
259 *函数参数 : (I)pFileName-文件名
260 *函数返回值 : true-执行成功,false-执行失败
261 *作者 : Ark Zhang
262 *函数创建日期 : 2012.11.28
263 *函数修改日期 : 
264 *修改人 :
265 *修改原因 :  
266 *版本 : 1.0
267 *历史版本 : 无
268 ***********************************************************************************************/
269 WIN32API bool AZ_PRINTSCREEN_SaveFullScreenToFile(const char *pFileName)
270 {
271     long nSrcWidth = GetSystemMetrics(SM_CXSCREEN)+2;//全屏
272     long nSrcHeight = GetSystemMetrics(SM_CYSCREEN);
273     char *pRGBBuf = new char[nSrcWidth*nSrcHeight*4];
274     long nLen = 0;
275     if (!AZ_PRINTSCREEN_GetFullScreenRGB(pRGBBuf, &nLen, &nSrcWidth, &nSrcHeight))
276     {
277         _TRACE("get screen RGB failed\n");
278     }
279     AZ_PRINTSCREEN_SaveRGBToFile(pFileName, pRGBBuf, nLen, nSrcWidth, nSrcHeight);
280     delete []pRGBBuf;
281     return true;
282 }
283 
284 /***********************************************************************************************
285 *函数名 : AZ_PRINTSCREEN_SetRGBBitsPixel
286 *函数功能描述 : 设置RGB数据位宽,24、32可选
287 *函数参数 : (I)nbits-位宽
288 *函数返回值 : true-执行成功,false-执行失败
289 *作者 : Ark Zhang
290 *函数创建日期 : 2012.11.28
291 *函数修改日期 : 
292 *修改人 :
293 *修改原因 :  
294 *版本 : 1.0
295 *历史版本 : 无
296 ***********************************************************************************************/
297 WIN32API bool AZ_PRINTSCREEN_SetRGBBitsPixel(long nbits)
298 {
299     if (24 == nbits || 32 == nbits)
300     {
301         m_nRGBBitsPixel = nbits;
302     }
303     else
304     {
305         return false;
306     }
307     return true;
308 }
309 
310 bool AZ_PRINTSCREEN_ShowOSD(HDC hdc, long lPicWidth, long lPicHeight)
311 {
312     CString csTemp = _T("");
313     SYSTEMTIME time;
314     GetLocalTime(&time);
315     csTemp.Format(_T("%02d/%02d/%04d  %02d:%02d:%02d"), 
316                   time.wDay, time.wMonth, time.wYear, 
317                   time.wHour, time.wMinute, time.wSecond);
318     SetTextColor(hdc, OSD_COLOR);
319     SetBkMode(hdc, TRANSPARENT);
320     CFont hFont;
321     hFont.CreateFont(lPicHeight/15, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET,
322                      OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,                                  
323                      DEFAULT_PITCH|FF_SWISS, _T("宋体"));
324     CDC dc;
325     dc.Attach(hdc);
326     CFont *pOldFont = dc.SelectObject(&hFont);
327     DrawText(hdc, csTemp, csTemp.GetLength(), CRect(10, 10, 500, 200), DT_LEFT);
328     dc.SelectObject(pOldFont);
329     return true;
330 }

 

你可能感兴趣的:(实现windows下屏幕指定区域截图功能)