最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)現(xiàn)屏幕截圖

 更新時(shí)間:2018年05月15日 14:18:44   作者:sunflover454  
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)屏幕截圖功能,截圖自動(dòng)保存為png格式文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

上回分享了一個(gè)全屏截圖的代碼,保存為BMP,參考:C++實(shí)現(xiàn)屏幕截圖(全屏截圖)

實(shí)際使用的過程中我發(fā)現(xiàn)截圖文件實(shí)在大,無奈又整成了PNG截圖,現(xiàn)在分享出來。

MakePNG.h

//MakePNG.h 
 
#pragma once 
#include <GdiPlus.h> 
using namespace Gdiplus; 
#pragma comment(lib,"GdiPlus.lib") 
 
class CMakePNG 
{ 
public: 
 CMakePNG(void); 
 ~CMakePNG(void); 
 
 BOOL MakePNG(HDC hDC,CRect rect,CString strFilePath); 
 BOOL BMptoPNG(LPCWSTR StrBMp,LPCWSTR StrPNG); 
 BOOL PNGtoBMp(LPCWSTR StrPNG,LPCWSTR StrBMp); 
 BOOL GetEncoderClsid(WCHAR* pFormat,CLSID* pClsid); 
private: 
 GdiplusStartupInput m_gdiplusStartupInput; 
 ULONG_PTR m_pGdiToken; 
}; 

MakePNG.cpp

//MakePNG.cpp 
 
#include "StdAfx.h" 
#include "MakePNG.h" 
 
CMakePNG::CMakePNG(void) 
{ 
 GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL); 
} 
 
CMakePNG::~CMakePNG(void) 
{ 
} 
 
/***************************************************************************/ 
/* 功能: 根據(jù)rect屏幕抓圖,保存為文件名為strFilePath的PNG圖像文件 */ 
/* 輸入?yún)?shù): HDC hDC   屏幕HDC;    */ 
/*  CRect rect  需要的矩形;   */ 
/*  CString strFilePath 保存文件全路徑(含后綴名); */ 
/***************************************************************************/ 
BOOL CMakePNG::MakePNG(HDC hDC, CRect rect, CString strFilePath) 
{ 
 BITMAP bmp; 
 PBITMAPINFO pbmi; 
 PBITMAPINFOHEADER pbih; // bitmap info-header 
 BITMAPFILEHEADER hdr; // bitmap file-header 
 WORD cClrBits; 
 LPBYTE lpBits;  // memory pointer 
 DWORD dwTmp; 
 DWORD cb;   // incremental count of bytes 
 BYTE *hp;   // byte pointer 
 HANDLE hfile;  // file handle 
 CString szBMPFilename = strFilePath.Left(strFilePath.GetLength() - 3) + _T("bmp");//先保存成位圖 
 HDC hdcCompatible = CreateCompatibleDC(hDC); 
 HBITMAP hbmScreen = CreateCompatibleBitmap(hDC, rect.Width(), rect.Height()); 
 
 if (hbmScreen == NULL) 
 { 
 AfxMessageBox(_T("CreateCompatibleBitmap() error")); 
 return FALSE; 
 } 
 
 // Select the bitmaps into the compatible DC. 
 
 if (!SelectObject(hdcCompatible, hbmScreen)) 
 { 
 AfxMessageBox(_T("Compatible Bitmap Selection error")); 
 return FALSE; 
 } 
 
 //Copy color data for the entire display into a 
 //bitmap that is selected into a compatible DC. 
 
 if (!BitBlt(hdcCompatible, 
 0,0, 
 rect.Width(), rect.Height(), 
 hDC, 
 rect.left,rect.top, 
 SRCCOPY)) 
 { 
 AfxMessageBox(_T("Screen to Compat Blt Failed")); 
 return FALSE; 
 } 
 
 // Retrieve the bitmap's color format, width, and height. 
 if (!GetObject(hbmScreen, sizeof(BITMAP), (LPSTR)&bmp)) 
 { 
 AfxMessageBox(_T("GetObject()出錯(cuò)!")); 
 return FALSE; 
 } 
 // Convert the color format to a count of bits. 
 cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 
 if (cClrBits == 1) 
 cClrBits = 1; 
 else if (cClrBits <= 4) 
 cClrBits = 4; 
 else if (cClrBits <= 8) 
 cClrBits = 8; 
 else if (cClrBits <= 16) 
 cClrBits = 16; 
 else if (cClrBits <= 24) 
 cClrBits = 24; 
 else cClrBits = 32; 
 
 // Allocate memory for the BITMAPINFO structure. (This structure 
 // contains a BITMAPINFOHEADER structure and an array of RGBQUAD 
 // data structures.) 
 
 if (cClrBits != 24) 
 pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
 sizeof(BITMAPINFOHEADER) + 
 sizeof(RGBQUAD) * (1<< cClrBits)); 
 
 // There is no RGBQUAD array for the 24-bit-per-pixel format. 
 
 else 
 pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
 sizeof(BITMAPINFOHEADER)); 
 
 // Initialize the fields in the BITMAPINFO structure. 
 
 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
 pbmi->bmiHeader.biWidth = bmp.bmWidth; 
 pbmi->bmiHeader.biHeight = bmp.bmHeight; 
 pbmi->bmiHeader.biPlanes = bmp.bmPlanes; 
 pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; 
 if (cClrBits < 24) 
 pbmi->bmiHeader.biClrUsed = (1<<cClrBits); 
 
 // If the bitmap is not compressed, set the BI_RGB flag. 
 pbmi->bmiHeader.biCompression = BI_RGB; 
 
 // Compute the number of bytes in the array of color 
 // indices and store the result in biSizeImage. 
 pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 
 * pbmi->bmiHeader.biHeight; 
 // Set biClrImportant to 0, indicating that all of the device colors are important. 
 pbmi->bmiHeader.biClrImportant = 0; 
 
 pbih = (PBITMAPINFOHEADER) pbmi; 
 lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); 
 
 if (!lpBits) 
 { 
 AfxMessageBox(_T("內(nèi)存分配錯(cuò)誤!")); 
 return FALSE; 
 } 
 // Retrieve the color table (RGBQUAD array) and the bits 
 // (array of palette indices) from the DIB. 
 if (!GetDIBits(hDC, hbmScreen, 0, (WORD) pbih->biHeight, lpBits, pbmi, 
 DIB_RGB_COLORS)) 
 { 
 AfxMessageBox(_T("GetDIBits() error")); 
 return FALSE; 
 } 
 
 // Create the .BMP file. 
 hfile = CreateFile(szBMPFilename, 
 GENERIC_READ | GENERIC_WRITE, 
 (DWORD) 0, 
 NULL, 
 CREATE_ALWAYS, 
 FILE_ATTRIBUTE_NORMAL, 
 (HANDLE) NULL); 
 if (hfile == INVALID_HANDLE_VALUE) 
 { 
  AfxMessageBox(_T("創(chuàng)建文件失敗")); 
 return false; 
 } 
 hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" 
 // Compute the size of the entire file. 
 hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + 
 pbih->biSize + pbih->biClrUsed 
 * sizeof(RGBQUAD) + pbih->biSizeImage); 
 hdr.bfReserved1 = 0; 
 hdr.bfReserved2 = 0; 
 
 // Compute the offset to the array of color indices. 
 hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
 pbih->biSize + pbih->biClrUsed 
 * sizeof (RGBQUAD); 
 
 // Copy the BITMAPFILEHEADER into the .BMP file. 
 if (!WriteFile(hfile, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
 (LPDWORD) &dwTmp, NULL)) 
 { 
  AfxMessageBox(_T("寫B(tài)MP文件頭失敗")); 
 return FALSE; 
 } 
 
 // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
 if (!WriteFile(hfile, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
 + pbih->biClrUsed * sizeof (RGBQUAD), 
 (LPDWORD) &dwTmp, ( NULL))) 
 { 
  AfxMessageBox(_T("寫B(tài)MP文件頭失敗")); 
 return FALSE; 
 } 
 
 // Copy the array of color indices into the .BMP file. 
 cb = pbih->biSizeImage; 
 hp = lpBits; 
 if (!WriteFile(hfile, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
 { 
 AfxMessageBox(_T("寫入BMP文件失敗")); 
 return FALSE; 
 } 
 
 // Close the .BMP file. 
 if (!CloseHandle(hfile)) 
 { 
  AfxMessageBox(_T("Can't close BMP file.")); 
 } 
 
 // Free memory. 
 GlobalFree((HGLOBAL)lpBits); 
 
 //轉(zhuǎn)換成PNG 
 if(!BMptoPNG(szBMPFilename,strFilePath)) 
 { 
 DeleteFile(szBMPFilename); 
 return FALSE; 
 } 
 DeleteObject(hbmScreen); 
 DeleteFile(szBMPFilename); 
 return TRUE; 
} 
// //轉(zhuǎn)換BMP文件為PNG文件  
BOOL CMakePNG::BMptoPNG(LPCWSTR StrBMp,LPCWSTR StrPNG) 
{ 
 CLSID encoderClsid; 
 Status stat; 
 Image* image = NULL; 
 image = Bitmap::FromFile(StrBMp,TRUE); 
 if (!GetEncoderClsid(L"image/png",&encoderClsid)) 
 { 
 return FALSE; 
 } 
 stat = image->Save(StrPNG,&encoderClsid,NULL); 
 if (stat != Ok) 
 { 
 return FALSE; 
 } 
 delete image; 
 return TRUE; 
} 
 
// 功能描述: 轉(zhuǎn)換PNG文件為BMP文件 
BOOL CMakePNG::PNGtoBMp(LPCWSTR StrPNG,LPCWSTR StrBMp) 
{ 
 CLSID encoderClsid; 
 Status stat; 
 Image* pImage; 
 pImage = Bitmap::FromFile(StrPNG,TRUE); 
 if (!GetEncoderClsid(L"image/bmp",&encoderClsid)) 
 { 
 return FALSE; 
 } 
 stat = pImage->Save(StrBMp,&encoderClsid,NULL); 
 if (stat != Ok) 
 { 
 return FALSE; 
 } 
 delete pImage; 
 return TRUE; 
} 
 
BOOL CMakePNG::GetEncoderClsid(WCHAR* pFormat,CLSID* pClsid) 
{ 
 UINT num = 0,size = 0; 
 ImageCodecInfo* pImageCodecInfo = NULL; 
 GetImageEncodersSize(&num,&size); 
 if (size == 0) 
 { 
 return FALSE; 
 } 
 pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); 
 if (pImageCodecInfo == NULL) 
 { 
 return FALSE; 
 } 
 GetImageEncoders(num,size,pImageCodecInfo); 
 BOOL bfound = FALSE; 
 for (UINT i = 0;!bfound && i < num; i++) 
 { 
 if (_wcsicmp(pImageCodecInfo[i].MimeType,pFormat) == 0) 
 { 
  *pClsid = pImageCodecInfo[i].Clsid; 
  bfound = TRUE; 
 } 
 } 
 free(pImageCodecInfo); 
 return bfound; 
} 

以上兩個(gè)文件實(shí)際上是CMakePNG類,使用時(shí)需要把他們添加到項(xiàng)目中,調(diào)用方法如下:

wstring GetAppPathW() 
{ 
 wchar_t szExePath[MAX_PATH] = {0}; 
 GetModuleFileNameW(NULL, szExePath, MAX_PATH); 
 wchar_t *pstr = wcsrchr(szExePath, '\\'); 
 memset(pstr + 1, 0, 2); 
 wstring strAppPath(szExePath); 
 return strAppPath; 
} 
 
// 屏幕截圖 
CString CDemoDlg::ScreenShot(void) 
{ 
 CWnd *pDesktop = GetDesktopWindow(); 
 CDC *pDC = pDesktop->GetDC(); 
 CRect rect; 
 //獲取窗口的大小 
 pDesktop->GetClientRect(&rect); 
 
 //保存到的文件名 
 CString strFileName(GetAppPathW().c_str()); 
 strFileName += _T("ScreenShot\\"); 
 CreateDirectory((LPCTSTR)strFileName,NULL); 
 CTime t = CTime::GetCurrentTime(); 
 CString tt = t.Format("%Y%m%d_%H%M%S"); 
 strFileName += tt; 
 strFileName += _T(".PNG"); 
 //保存為PNG 
 CMakePNG MakePNG; 
 MakePNG.MakePNG(pDC->m_hDC,rect,strFileName); 
 ReleaseDC(pDC); 
 return strFileName; 
} 

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語言實(shí)現(xiàn)超市計(jì)價(jià)收款系統(tǒng)

    C語言實(shí)現(xiàn)超市計(jì)價(jià)收款系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)超市計(jì)價(jià)收款系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言 二叉查找樹性質(zhì)詳解及實(shí)例代碼

    C語言 二叉查找樹性質(zhì)詳解及實(shí)例代碼

    這篇文章主要介紹了C語言 二叉查找樹性質(zhì)詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Qt帶參數(shù)的信號和槽函數(shù)舉例詳解

    Qt帶參數(shù)的信號和槽函數(shù)舉例詳解

    信號槽的設(shè)計(jì)旨在實(shí)現(xiàn)控件和處理邏輯的解耦合,但在實(shí)際開發(fā)中,一對一的關(guān)系更為常見,這篇文章主要介紹了Qt帶參數(shù)的信號和槽函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2025-03-03
  • Cocos2d-x UI開發(fā)之CCControlColourPicker控件類使用實(shí)例

    Cocos2d-x UI開發(fā)之CCControlColourPicker控件類使用實(shí)例

    這篇文章主要介紹了Cocos2d-x UI開發(fā)之CCControlColourPicker控件類使用實(shí)例,本文代碼中包含大量注釋來講解CCControlColourPicker控件類的使用,需要的朋友可以參考下
    2014-09-09
  • Inline Hook(ring3)的簡單C++實(shí)現(xiàn)方法

    Inline Hook(ring3)的簡單C++實(shí)現(xiàn)方法

    這篇文章主要介紹了Inline Hook(ring3)的簡單C++實(shí)現(xiàn)方法,需要的朋友可以參考下
    2014-08-08
  • C++與Lua交互原理實(shí)例詳解

    C++與Lua交互原理實(shí)例詳解

    這篇文章主要介紹了C++與Lua交互原理實(shí)例詳解,有感興趣的同學(xué)可以研究下
    2021-02-02
  • C語言三分鐘精通時(shí)間復(fù)雜度與空間復(fù)雜度

    C語言三分鐘精通時(shí)間復(fù)雜度與空間復(fù)雜度

    算法復(fù)雜度分為時(shí)間復(fù)雜度和空間復(fù)雜度。其作用:?時(shí)間復(fù)雜度是度量算法執(zhí)行的時(shí)間長短;而空間復(fù)雜度是度量算法所需存儲(chǔ)空間的大小
    2022-02-02
  • Matlab實(shí)現(xiàn)繪制雷達(dá)圖(蜘蛛圖)

    Matlab實(shí)現(xiàn)繪制雷達(dá)圖(蜘蛛圖)

    這篇文章主要為大家詳細(xì)介紹了如何利用Matlab實(shí)現(xiàn)雷達(dá)圖(蜘蛛圖)的繪制,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Matlab有一定幫助,需要的可以參考一下
    2022-09-09
  • C++常見容器獲取頭元素的方法大全

    C++常見容器獲取頭元素的方法大全

    在C++編程中,容器是存儲(chǔ)和管理數(shù)據(jù)集合的重要工具,不同的容器提供了不同的接口來訪問和操作其中的元素,獲取容器的頭元素(即第一個(gè)元素)是常見的操作之一,本文將詳細(xì)列舉C++標(biāo)準(zhǔn)庫中所有常見容器獲取頭元素的方法,并對每種方法進(jìn)行簡要說明,需要的朋友可以參考下
    2025-03-03
  • C語言手寫集合List的示例代碼

    C語言手寫集合List的示例代碼

    數(shù)組長度是固定的,那么在很多時(shí)候我們并不知道到底有多少數(shù)據(jù)需要存儲(chǔ),這時(shí)候我么就需要一個(gè)可變長度的數(shù)組來進(jìn)行存儲(chǔ),在C語言中需要我們自己進(jìn)行定義,我們稱為集合。本文將用C語言實(shí)現(xiàn)手寫集合,需要的可以參考一下
    2022-08-08

最新評論

平湖市| 襄城县| 永城市| 平南县| 涟水县| 合肥市| 阿坝县| 玉门市| 陈巴尔虎旗| 孝昌县| 榕江县| 深州市| 衡水市| 安多县| 来凤县| 湘潭市| 铁力市| 嘉黎县| 汕头市| 东阳市| 苗栗市| 湖南省| 佛学| 凤庆县| 塔城市| 嘉义市| 荆门市| 新野县| 和硕县| 新龙县| 巴彦淖尔市| 达日县| 嵩明县| 姜堰市| 丰都县| 托克逊县| 久治县| 武强县| 慈利县| 凭祥市| 即墨市|