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 }