引言
最近有一個需要截取當前屏幕,並保存成BMP文件的需求。整個需求,拆分成三步:1、截取屏幕,獲得位圖數據。2、配合bmp文件結構信息,將數據整合。3、對整合后的數據做操作,如保存在本地、通過網絡傳送至服務器等。
截屏
我選用的是BitBlt這個windows API作為截取圖片的方法,該方法的詳細信息參考這里,詳細代碼如下:
首先獲得屏幕的HDC,通過GetDC()這個API,接着創建一個兼容HDC,即comHDC,用來在內存里表示截取的位圖的上下文。 后面兩行代碼分別是獲得屏幕的寬度和高度。然后用CreateCompatibleBitmap這個API創建一個兼容的HBITMAP,即我們的位圖句柄。創建好后,我們將其作為comHDC的選中位圖句柄(在這里,我不知道怎么措辭了,如果專門的措辭,請告知。)。然后調用BitBlt,將hDC即屏幕的位圖復制到comHDC即hBitmap中。至此,我們已經獲得到所需位圖數據的全部信息。
BMP文件結構信息
bmp文件需由三部分組成:文件頭(BITMAPFILEHEADER),位圖信息頭(BITMAPINFOHEADER)、位圖數據。我們將這所有的數據寫入硬盤的時候,需要按照順序依次將三個部分寫入。文件頭和位圖信息頭是按照HBitmap以及它的HDC來構造的。構造文件頭的代碼如下:
其中width和height為上文得到的屏幕寬高,其他數值請參考MSDN。
位圖信息頭的構造,代碼如下:
得到位圖數據的代碼如下:
在這里主要運用GetDIBits來獲得數據,存儲在lpbitmap里面。至此,我們獲得了所有的需要的數據:bmiHeader(文件頭)、bmfHeader(位圖信息頭)、lpbitmap(位圖數據)。
整合數據
我們先來談談保存至硬盤。由於需要寫入文件元信息,我們需要用二進制的方式寫文件,運用C++標准庫,代碼如下:
此時,就可以在項目目錄里面獲得一個存有當前屏幕快照的bmp文件了。
現在,我們發揮一下想象力,如果這段程序運行在別人的電腦上,通過這段程序,我們獲得了他or她的屏幕快照,為了避免被發現這些操作,我們不能保存這些數據在硬盤上,直接將這些數據傳到我們這……。我們可以整合這些數據,將它們存放在任何我們想要存放的地方:DB,服務器,硬盤等等。我們將所有的數據整合成一個二進制數據塊:
現在,所有的信息都放在allData里面了, 我們可以寫入文件:
可以通過socket傳送到網絡的另一端,然后再保存,也可以直接存入數據庫。whatever u want!
總結
C++在底層用起來非常方便,可以隨意轉換數據,只要我們確定數據的結構及其大小即可。代碼我就不上傳了,非常短,別忘了釋放new出的內存以及創造的兼容HDC等資源哦。








