青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

幽幽
 
posts - 51,  comments - 28,  trackbacks - 0
一、 簡介

屏幕抓圖程序在處理圖形中應用廣泛。作為Windows XP及以后版本操作系統(tǒng)的圖形處理內(nèi)核,GDI+在二維幾何圖形處理、圖像顯示與轉(zhuǎn)換和字符排版等方面簡直是傳統(tǒng)GDI程序員的一種解脫。但是,至少在目前情況下,GDI+尚不能完全代替GDI。與GDI相比,它至少還存在以下不足:

不支持從內(nèi)存到屏幕的位傳輸操作;

不支持光柵“位運算”操作;

如果程序性能、速度要求比較嚴格,在圖片輸出方面的表現(xiàn)較差時,GDI往往能取代實現(xiàn)高性能的輸出。

本文通過對流行的屏幕抓圖程序工作原理的剖析,力圖向讀者闡明GDI+與GDI各自在圖形處理方面的優(yōu)缺點,并給出相應的VC++ .NET代碼實現(xiàn)。

    二、 GDI在抓圖中的關(guān)鍵作用

    要實現(xiàn)屏幕抓圖,關(guān)鍵有兩點:一是獲取圖片所在窗口的窗口句柄,即在何處捕獲圖片;二是保存抓取的圖片,實現(xiàn)這一點正是GDI+的強項。

    對于問題一,可以利用SetCapture函數(shù),它能夠追蹤鼠標指針的移動(包括在屏幕抓圖程序窗口之外的窗口)。在移動鼠標的過程中,它還可以根據(jù)鼠標的指針所在位置來判斷當前窗口的窗口句柄。我們還可以使用函數(shù)WindowFromPoint,這個函數(shù)能夠找出鼠標指針當前位置所對應的窗口句柄。

    使用過知名的抓圖軟件SnagIT的讀者都知道,在選擇抓圖窗口時,鼠標指針所在位置的窗口都會出現(xiàn)加粗的紅色邊框,以提醒目前所選擇的窗口,這個功能實現(xiàn)起來有些復雜。下面介紹在GDI中如何使這個紅色邊框出現(xiàn)。

    【注意】正是由于這個紅色邊框的實現(xiàn),讀者才能發(fā)現(xiàn)GDI+在這方面的弱點。

在GDI中,一個最基本的概念就是設備環(huán)境(DC),每一個窗口都具有自己的DC。如果能夠找到窗口的DC,那么,用戶就能夠在該窗口的任何位置繪圖。然而,在屏幕抓圖程序中,由于用戶所選擇的窗口不固定,所以,要想得到鼠標指針所處窗口的DC并不容易。這一問題的答案在于GetDC函數(shù)。下面是GetDC的函數(shù)聲明:

HDC GetDC(HWND hWnd);

    這里,hWnd是DC對應的窗口句柄。注意,當hWnd為空時,該函數(shù)返回的是整個屏幕的設備環(huán)境句柄。這就意味著,開發(fā)人員可以在屏幕上的任何位置進行任意的繪圖操作。

    在鼠標指針所處的窗口繪圖時,繪圖的目的只是為了提醒用戶目前所選擇的窗口,所以,在繪圖時,必須保證不會破壞窗口原有的畫面。這時可將窗口的繪圖模式設為RS_NOTXORPEN,將畫筆顏色與屏幕顏色進行異或運算之后,再對屏幕顏色取反即可。RS_NOTXORPEN運算方式的特點在于:對同一像素進行兩次RS_NOTXORPEN運算后,像素值并不會發(fā)生變化。這樣,在同一個地方進行兩次繪圖后,窗口的畫面并不會發(fā)生任何變化。

    【注意】這些功能在GDI+中很難實現(xiàn)。

    三、 編碼實現(xiàn)

由上可知,屏幕抓圖至少分為3個步驟:

    (1) 啟用鼠標指針捕獲。

    (2) 在鼠標指針所在處的窗口進行繪圖,提示抓圖的目標。

    (3) 選定目標窗口時,將目標窗口的畫面保存為自定義的位圖并終止鼠標指針捕獲。

    以下是具體的編程步驟:

    (1)在Visual C++ .NET中按照GDI+程序的框架新建一個基于對話框的項目ScreenCapture,然后準備好一個外形為相機的光標文件(*.cur),將之引入資源管理器(IDC_CAMERA)。接著在CScreenCaptureDlg類中加入以下兩個全局變量:

HWND hwndCapture;

Crect rectCapture;

   (2)通過類向?qū)Ъ尤雽M_MOUSEMOVE及WM_LBUTTONUP事件的響應函數(shù),分別如下所示。

void CScreenCaptureDlg::OnMouseMove(UINT nFlags, CPoint point)

{

//如果用戶按隹鼠標左鍵不放,則開始抓取圖片

if(nFlags==MK_LBUTTON){

//隱藏程序窗口,以免影響在抓取時的“視野”

ShowWindow(SW_HIDE);

//載入“照相機”鼠標指針,開始追蹤鼠標指針的移動

HCURSOR cur=LoadCursor(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDC_CAMERA));

SetCursor(cur);

SetCapture();

//獲得鼠標指針所在窗口的句柄

this->ClientToScreen(&point);

hwndCapture=(HWND)::WindowFromPoint(point);

//取得屏幕的設備環(huán)境句柄,以便在屏幕的任何位置繪圖

HDC hDC=::GetDC(NULL);

//建立一個紅色的畫筆

HPEN hPen=CreatePen(PS_INSIDEFRAME,6,RGB(255,0,0));

//將繪圖模式設為R2_NOTXORPEN,在繪圖時可以不破壞原有的背景

int nMode=SetROP2(hDC,R2_NOTXORPEN);

HPEN hpenOld=(HPEN)SelectObject(hDC,hPen);

//得到鼠標指針所在窗口的區(qū)域

::GetWindowRect(hwndCapture,&rectCapture);

//在鼠標指針所在處的窗口四周畫一紅色的矩形,做為選定時的提示

POINT pt[5];

pt[0]=CPoint(rectCapture.left,rectCapture.top);

pt[1]=CPoint(rectCapture.right,rectCapture.top);

pt[2]=CPoint(rectCapture.right,rectCapture.bottom);

pt[3]=CPoint(rectCapture.left,rectCapture.bottom);

pt[4]=CPoint(rectCapture.left,rectCapture.top);

::Polyline(hDC,pt,5);

//延時后再重繪紅色矩形,這樣不會破壞原有的內(nèi)容

Sleep(100);

::Polyline(hDC,pt,5);

::SelectObject(hDC,hpenOld);

::ReleaseDC(NULL,hDC);

}

CDialog::OnMouseMove(nFlags, point);

}

void CScreenCaptureDlg::OnLButtonUp(UINT nFlags, CPoint point)

{

// 得到鼠標指針所在窗口的區(qū)域?qū)挕⒏?br>
int nWidth=rectCapture.Width();

int nHeight=rectCapture.Height();

HDC hdcScreen,hMemDC;

HBITMAP hBitmap,hOldBitmap;

//建立一個屏幕設備環(huán)境句柄

hdcScreen=CreateDC("DISPLAY",NULL,NULL,NULL);

hMemDC=CreateCompatibleDC(hdcScreen);

//建立一個與屏幕設備環(huán)境句柄兼容、與鼠標指針所在窗口的區(qū)域等大的位圖

hBitmap=CreateCompatibleBitmap(hdcScreen,nWidth,nHeight);

//把新位圖選到內(nèi)存設備描述表中

hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);

//把屏幕設備描述表拷貝到內(nèi)存設備描述表中

BitBlt(hMemDC,0,0,nWidth,nHeight,hdcScreen,rectCapture.left,rectCapture.top,SRCCOPY);

DeleteDC(hdcScreen);

DeleteDC(hMemDC);

//返回位圖句柄

//打開剪貼板,并將位圖拷到剪貼板上

OpenClipboard();

EmptyClipboard();

SetClipboardData(CF_BITMAP,hBitmap);

//關(guān)閉剪貼板

CloseClipboard();

MessageBox("屏幕內(nèi)容已經(jīng)拷到剪貼板!");

ReleaseCapture();

//恢復窗口顯示模式

ShowWindow(SW_NORMAL);

CDialog::OnLButtonUp(nFlags, point);

}

    至此,一個具有專業(yè)效果的屏幕抓圖程序的核心已經(jīng)搞定。

    四、 用GDI+實現(xiàn)畫面的保存

    經(jīng)過上面兩步,如果用戶在對話框中按住鼠標左鍵不放,程序便開始“抓圖”。當選擇好抓圖的目標后,松開鼠標左鍵,抓圖的目標窗口的畫面就自動保存到剪貼板中了。但是,把畫面保存到文件中更為重要。如果用GDI的方式來操作,需要對各種類位圖的結(jié)構(gòu)有詳盡的了解,極其麻煩。但如果用GDI+來實現(xiàn)之則極為容易。下面介紹如何將已經(jīng)抓到的圖片保存到一個BMP文件中。

由上面知,抓圖程序已經(jīng)得到了所捕獲的窗口的位圖句柄,接下來要將位圖句柄保存為相應的位圖文件。這一切歸功于GDI+的Bitmap類,詳見下列代碼。

void CScreenCaptureDlg::OnLButtonUp(UINT nFlags, CPoint point)

{

//……省略

if(GetSaveFileName(&ofn))

{

CLSID pngClsid;

Bitmap bmp(hBitmap,NULL);

//獲取BMP文件的編碼方式

GetEncoderClsid(L"image/bmp",&pngClsid);//幫助函數(shù)

CString tmp(ofn.lpstrFile);

CStringW filename((LPCSTR)tmp);

//保存所截取的屏幕圖片

bmp.Save(filename,&pngClsid);

}

ReleaseCapture();

MessageBox("屏幕內(nèi)容已經(jīng)保存到文件中!");

//恢復窗口顯示模式

ShowWindow(SW_NORMAL);

CDialog::OnLButtonUp(nFlags, point);

}

    五、 小結(jié)

    本文通過一個專業(yè)的屏幕抓圖程序的核心實現(xiàn),對比分析了GDI與GDI+各自的優(yōu)缺點。但我們相信,GDI+作為新一代圖形引擎,隨著版本的不斷升級,其遲早要淘汰掉GDI。本人拙見,不足處還望讀者指正。

另外,本文源碼在Windows 2000/VC++.NET 2003環(huán)境中調(diào)試通過。調(diào)試過程中注意:

確保工程對GDI+庫的正確引用:在頭文件stdafx.h中要加入相應引用;在應用程序類的InitInstance成員函數(shù)前后及其析構(gòu)函數(shù)中加適當?shù)牟僮鳎还こ叹幾g時要加入對gdiplus.lib的引用(“項目”|“添加現(xiàn)有項”,我的機器上是在C:\Program Files\Microsoft Visual Studio.NET\vc7\platformSDK\lib下找到庫文件)。

 

posted on 2008-08-13 23:02 幽幽 閱讀(2039) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理



<2008年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用鏈接

留言簿(6)

隨筆分類(35)

隨筆檔案(51)

文章分類(3)

文章檔案(3)

相冊

我的鏈接

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美中日韩免费视频| 一区二区在线观看av| 亚洲一级片在线观看| 亚洲精品一区二区三区av| 最新成人在线| 久久夜色精品一区| 欧美11—12娇小xxxx| 亚洲国产欧美不卡在线观看| 最新成人av在线| 中文精品视频| 午夜在线视频一区二区区别| 久久久噜噜噜久久| 欧美国产精品专区| 国产精品高清在线| 精品电影一区| 亚洲午夜久久久| 欧美主播一区二区三区美女 久久精品人| 小黄鸭视频精品导航| 久久视频这里只有精品| 欧美国产综合| 亚洲在线播放| 蜜桃av一区二区| 国产精品乱码一区二区三区 | 美日韩丰满少妇在线观看| 久久久综合视频| 欧美日在线观看| 精品福利电影| 亚洲制服av| 亚洲第一福利在线观看| 亚洲免费视频一区二区| 欧美ed2k| 在线电影国产精品| 亚洲一二区在线| 亚洲盗摄视频| 欧美一区二区三区四区在线 | 狠狠色丁香婷婷综合| 中国日韩欧美久久久久久久久| 欧美专区在线播放| 欧美激情精品久久久六区热门| 亚洲婷婷在线| 欧美国产另类| 亚洲人成网在线播放| 久久精品视频播放| 99re6这里只有精品| 免费日韩成人| 在线看欧美日韩| 久久久久欧美精品| 亚洲无限av看| 国产精品国产三级欧美二区| 亚洲美女av电影| 亚洲国产精品久久久久秋霞不卡 | 免费国产自线拍一欧美视频| 亚洲天堂成人在线观看| 欧美激情一区二区| 亚洲国产精品美女| 欧美黑人在线播放| 免费看黄裸体一级大秀欧美| 国产一区视频观看| 久久精品亚洲精品| 欧美在线91| 国产日韩欧美一区| 欧美在线影院| 久久电影一区| 在线观看久久av| 欧美成人首页| 欧美国产日韩a欧美在线观看| 亚洲国产精品久久久久久女王| 欧美不卡视频一区| 欧美18av| 日韩视频免费观看| 亚洲精品一级| 国产精品一级久久久| 香港成人在线视频| 欧美一区二区三区男人的天堂 | 亚洲已满18点击进入久久| 国产精品美女久久| 欧美在线播放一区| 欧美在线观看视频在线| 精品电影一区| 亚洲巨乳在线| 国产伦精品免费视频| 久久久久国产一区二区三区四区 | 欧美国产日韩一区| 欧美日韩亚洲不卡| 久久av资源网站| 美女精品国产| 亚洲男人av电影| 久久久久久精| 亚洲视频图片小说| 久久gogo国模裸体人体| 99国产精品国产精品毛片| 亚洲一区欧美激情| 久久男人av资源网站| 国产主播在线一区| 久久永久免费| 欧美精品尤物在线| 欧美综合国产精品久久丁香| 久久综合电影| 亚欧美中日韩视频| 免费国产自线拍一欧美视频| 亚洲一区二区三区在线播放| 欧美在线视频一区| 在线视频日韩精品| 久久精品视频导航| 欧美极品在线视频| 久久精品一本| 国产精品久久久久99| 欧美成人日韩| 国内精品模特av私拍在线观看| 最新成人av网站| 亚洲电影免费| 欧美在线一区二区三区| 亚洲综合成人在线| 欧美成人在线免费观看| 久久久精品国产免费观看同学 | 欧美日韩国产综合新一区| 久久偷窥视频| 国产日韩欧美一区二区| 99pao成人国产永久免费视频| 一区二区三区在线观看视频| 亚洲一区欧美| 亚洲自拍偷拍一区| 欧美伦理在线观看| 亚洲国产日韩一级| 91久久夜色精品国产九色| 久久精品在线播放| 久久久九九九九| 国产视频欧美视频| 亚洲欧美一级二级三级| 亚洲自拍偷拍麻豆| 欧美视频在线观看一区| 亚洲欧洲视频在线| 亚洲免费成人| 欧美日本一区二区三区| 亚洲二区三区四区| 亚洲日本中文字幕| 欧美本精品男人aⅴ天堂| 欧美成人资源网| 亚洲欧洲日本国产| 欧美日本一道本| 亚洲天堂激情| 久久免费观看视频| 亚洲国产精品国自产拍av秋霞| 欧美xart系列在线观看| 亚洲国产成人在线播放| 日韩亚洲综合在线| 欧美色精品天天在线观看视频| 亚洲美女黄网| 亚洲欧美国产日韩天堂区| 国产精品私拍pans大尺度在线| 亚洲午夜精品久久| 久久精品一区二区三区不卡牛牛 | 亚洲欧美日韩国产综合| 国产欧美一区在线| 欧美激情四色 | 久久国产精品第一页| 欧美日韩精品一区二区| 日韩午夜精品视频| 欧美一区二区免费视频| 国产真实久久| 欧美成人激情在线| 99精品国产在热久久| 欧美亚洲自偷自偷| 在线看一区二区| 欧美视频1区| 欧美在线国产| 亚洲国产另类久久久精品极度| 亚洲一区二区成人在线观看| 国产亚洲激情视频在线| 欧美成年人视频| 亚洲无线一线二线三线区别av| 午夜国产不卡在线观看视频| 精品成人a区在线观看| 国产精品ⅴa在线观看h| 久久全球大尺度高清视频| 99国内精品久久| 老司机久久99久久精品播放免费| 亚洲精品一区久久久久久| 国产精品日韩高清| 久久亚洲欧洲| 一本不卡影院| 欧美国产先锋| 久久精品一本| 亚洲欧美三级在线| 日韩视频久久| 亚洲精品久久久久久久久| 国产麻豆日韩欧美久久| 欧美日韩成人综合在线一区二区| 久久精品人人做人人综合 | 日韩视频在线观看免费| 久久夜色精品国产欧美乱极品| 一本色道久久综合精品竹菊| 国语自产精品视频在线看8查询8| 欧美日韩午夜在线| 欧美韩日一区二区三区| 久久激情五月丁香伊人| 亚洲免费视频在线观看| 亚洲人久久久| 欧美www视频在线观看| 欧美在线一二三|