VC+ + 視圖內容導出成位圖的方法

VC+ + 視圖內容導出成位圖的方法

張 弦, 鮑徵宇

(中國地質大學地球化學研究所, 武漢 430074)

摘 要: 爲了獲得程序視圖的內容, 我們多采用屏幕硬拷貝的方法, 在視圖內容較多, 需要滾屏顯示的時候, 這種方法尤其費時費力, 且在圖形拼合時易產生偏差。作者在本文中介紹了在VC+ + 編程中直接把視圖內容導出成位圖文件的方法, 闡述了基本原理, 並提供了源代碼。

關鍵詞: 位圖; 導出; VC+ + ; 圖形圖像; 文檔/視圖

Microsoft Visual C+ + 6. 0 Windows 操作系統中程序設計的利器, 並有強大的圖形圖像編程能力。在進行數值圖像處理(如遙感圖像處理、巖礦顯微組構的數值圖像分析等) , 常用VC+ + 作爲編程工具,程序運行結果多以圖形(: 直方圖、等值線圖、曲線圖、以符號描述的目標物體分佈圖)、圖像(如岩石顯微圖像的礦物邊界的圈定及目標物體的分割) 的形式呈現。爲了保存程序視圖的內容, 我們平時多用的是屏幕拷貝再粘貼至其它圖像處理軟件(: Photoshop) 中。編輯保存成圖像文件的方法, 不能實現程序本身把視圖內容導出成圖像的功能, 在保存視圖內容時不方便, 尤其是在視圖內容較多, 需要滾屏顯示時, 要分次

對屏幕進行硬拷貝, 再採用圖像處理軟件進行裁剪、拼合的方法, 費時費力, 而且多個小圖像拼合成一個大圖像時也存在偏差。作者在文中介紹了把視圖內容(全部或局部) 直接導出成位圖文件的方法, 易於編程實現。

1 基本原理

Windows系統中有兩種類型的位圖: 設備相關位圖(Device Dependent Bitmap, 簡稱DDB) 和設備無關位圖(Device Independent Bitmap, 簡稱DIB)DDB 是一種內部位圖格式, 它們在內存中的結構和位置依賴於管理它們的設備驅動程序, 顯示的圖像依計算機顯示系統的不同而不同, 因此, 一般不存儲爲文件。與DDB 相比, D IB 是一種外部的位圖格式, 文件的結構與計算機系統硬件無關, 因此, 在不同的顯示系統中具有相同的顯示結果, 常存儲爲以. bmp 爲後綴的文件。

Ms VC+ + 6.0 基於Document/View 結構的程序中, 由視圖類的OnDraw(CDC* pDC) 函數在窗口客戶區中顯示文字、圖形、圖像等視圖內容。位圖的顯示就是把位圖顯示在屏幕上, 其反過程就是在截取屏幕的指定區域內放入位圖。顯示一幅D IB 位圖圖像的方法之一是先把D IB 位圖轉換成DDB 位圖bmp, 再把bmp 位圖選入設備繪圖環境(Device Context) pDC2>SelectObject (&bmp) , 調用BitBlt () 函數畫至顯示屏, 即可完成位圖的顯示。DDB 位圖選入設備繪圖環境後, 在設備環境沒有選入新的繪圖對象之前, 其視圖內容就與DDB 位圖的內容一致。我們可以通過更改視圖內容來更改被選入設備繪圖環境的DDB 位圖。

這樣就可以獲得視圖的DDB 位圖, 再把DDB 轉換成D IB, 完成D IB 位圖的保存即可。

2 實現代碼詳解

211 DDB 位圖的生成與視圖內容的獲取

以下的代碼要加入到視圖類的成員函數中。

CBitmap bmp;        //用於保存視圖的內容的DDB 位圖

CDC memDC;         //與當前顯示設備相兼容的內存設備環境

CSize sizeTotal= GetTotalSize () ;   //獲取全部視圖的大小, 在這裏可以通過

                  //指定sizeTotal 來獲取視圖中特定的區域

int nMemDC;              //保存顯示設備環境, 用於恢復初始設備環境

nMapMode= MM-LOENGLISH;       //顯示模式, MM-LOENGLISH

int bits= GetDC()->GetDeviceCaps(BITSPIXEL )*GetDC()->GetDeviceCaps(PLANES);

                    //獲取顯示設備的顏色表位數

bmp.CreateBitmap( sizeTotal.cx, sizeTotal.cy, 1, bits, NULL ) ;   //創建DDB 視圖, 大小由sizeTotal 來指定

memDC.CreateCompatibleDC(GetDC() ) ;   //創建兼容的內存設備環境

nMemDC= memDC.SaveDC() ;       //保存設備環境的初始狀態

memDC.SelectObject(&bmp) ;        //DDB 位圖選入繪圖設備

memDC.FillSolidRect(0, 0, sizeTotal. cx, sizeTotal. cy, GetDC()->GetBkColor () ) ;

                  //以當前視圖的背景色來填充位圖(初始化位圖)

memDC.SetMapMode(nMapMode) ;

OnDraw(&memDC) ;            //完成視圖內容的獲取

memDC.RestoreDC(nMemDC) ;       //恢復至設備環境的初始狀態

212 DDB 位圖轉換成D IB 位圖

由於D IB 圖像的每行都被填充到一個四字節邊界, 因此需要經常計算其每行所實際佔用的倍數。宏WIDTHBYTE 將一個數對齊於四字節邊界, 可方便地用於計算D IB 行的長度, 定義如下:

#define WIDTHBYTES(bits) ( ( ( (bits) + 31)/ 32) 3 4)

// pBmp 是傳遞過來的要轉換的DDB 位圖的指針, pDC 爲顯示設備環境的指針

//函數返回DIB 位圖的句柄

//全局函數

HGLOBAL ConvertDDB2D IB (CBitmap* pBmp, CDC3 pDC)

{

  BITMAPINFOHEADER bi;    //DIB 位圖信息頭

LPBITMAPINFO lpBi;      //DIB 位圖信息指針

BITMAP bm;

DWORD dwSizeCT;

DWORD dwDibL en;

HGLOBAL hData;

pBmp2> GetBitmap(&bm) ;   //獲得B ITMA P 結構

bi.biSize= sizeof (BITMAPINFOHEADER);

bi.biW idth= bm.bmW idth;

bi.biHeight= bm.bmHeigh t;

bi.biP lanes= bm.bmPlanes;

bi.biBitCount= bm. bmPlanes* bm.bmBitsPixel;

bi.biSize Image= 0;

bi.biXPelsPerM eter= 0;

bi.biYPelsPerM eter= 0;

bi.biComp ression= B I- RGB;

bi.biClrUsed= 0;

bi.biClrImportant= 0;

switch (bi. biB itCoun)

{

      case 1:    {dwSizeCT= 2;  break;  }

case 4:    {dwSizeCT= 16;  break;  }

case 8:    {dwSizeCT= 256;  break;  }

case 24:    {dwSizeCT= 0;  break;  }

default:    {dwSizeCT= 0;     }

  }

  dwDibL en= bi.biSize+ dwSizeCT* sizeof(RGBQUAD) ;

hData= ::GlobalAlloc(GHND, dwDibLen) ;

lpBi= (LPBITMAPINFO) ::GlobalLock(hData);

lpBi2>bmiHeader= bi;

//獲得DIB 位圖文件信息, 即爲lpBi賦值

VERIFY                                             

(

  ::GetDIBits

  (

  pDC2>GetSafeHdc() ,

(HBITMAP)pBmp2>GetSafeHandle() ,

0,(WORD)bi.biHeight,

NULL ,

lpBi,

DIB- RGB- COLORS

  )

) ;

DWORD dwErr;

dwErr= GetLastError () ;

bi= lpBi2>bmiHeader;     //獲得D IB 位圖信息頭

::GlobalUnlock(hData) ;

//計算位圖大小( inbytes)

if (! bi.biSizeImage)

{

  bi.biSizeImage= WIDTHBYTES (bi.biBitCount* bi. biWidth) *bi.biHeight;

}

dwDibLen+ = bi.biSizeImage;

hData= ::GlobalReAlloc(hData, dwDibLen, CHND) ;

ASSERT (hData) ;

lpBi= (LPBITMAPIN FO) ::GlobalLock(hData) ;

ASSERT ( lpBi) ;

//複製DDB 位圖內容到DIB 位圖

V ER IFY

(

  ::GetDIBits

(

pDC->GetSafeHdc(),

(HBITMAP)pBmp->GetSafeHandle() ,

0,

(WORD) bi. biHeigh t,

(L PSTR) lpB i+ sizeof (B ITMA P IN FOHEADER) + dw SizeCT3 sizeof (RGBQUAD) ,

lpB i,

D IB- RGB- COLORS

)

) ;

: : GlobalU nlock (hData) ;

return hData;

}

213 保存D IB 位圖

öö hD ib D IB 位圖的句柄

ööstrN ame 爲保存文件的全路徑名

öö全局函數

·88· 物探化探計算技術24

void SaveD ibBmp (HGLOBAL hD ib, CString strN ame)

{

B ITMA PF IL EHEADER bmf;   ööD IB 位圖文件頭

B ITMA P IN FOHEADER bi;    ööD IB 位圖信息頭

L PB ITMA P IN FOHEADER lpB i;  ööD IB 位圖信息頭指針

CF ile file;

CF ileExcep tion fxError;

DWORD dw SizeCT;

lpB i= (L PB ITMA P IN FOHEADER) : : GlobalLock (hD ib) ;  öö獲得D IB 信息頭指針

bi= 3 lpB i;

if (! bi. biSize Image) bi. biSize Image= W IDTHBYTES (bi. biB itCount3 bi. biW idth) 3 bi. biHeigh t;

sw itch (bi. biB itCoun)  öö獲取每個像素所需要的位數

{

  case 1:    { dw SizeCT= 2;  break; }

case 4:    { dw SizeCT= 16;  break; }

case 8:    { dw SizeCT= 256; break; }

case 24:   { dw SizeCT= 0;  break; }

default:    { dw SizeCT= 0;     }

}

öö獲得位圖文件頭的詳細信息

bmf. bfType= MB;

bmf. bfSize= sizeof (bmf) + : : GlobalSize (hD ib) ;

bmf. bfOffB its= sizeof (bmf) + bi. biSize+ dw SizeCT3 sizeof (RGBQUAD) ;

bmf. bfReserved1= 0;

bmf. bfReserved2= 0;

ööCF ile 創建一個二進制文件

if (! file. Open (strN ame, CF ile: :modeCreateûCF ile: :modeW rite, &fxError) )

{

  TCHAR buf [255 ];

fxError. GetErrorM essage (buf, 255) ;    öö獲得出錯信息

A fxM essageBox (buf) ;          öö顯示出錯信息

return;

}

öö寫入D IB 文件頭及文件內容

file. W rite (&bmf, sizeof (B ITMA PF IL EHEADER) ) ;

file. W rite ( (L PSTR) lpB i, bi. biSize+ dw SizeCT3 sizeof (RGBQUAD) + bi. biSize Image) ;

file. Close () ;

öö進行清除

: : GlobalU nlock (hD ib) ;

: : GlobalF ree (hD ib) ;}

3 結束語

作者在本文中解決了VC+ + 程序視圖內容導出的問題, 可方便的把視圖內容導出成位圖。作者在文中

給出了關鍵代碼, 直接把相關代碼複製到程序中便可實現位圖導出功能。訪問鏈接h ttp: ööw altzforever.

edu. ch inaren. com , 下載Output. zip 文件可得到演示程序與完整演示程序源代碼。本文中所使用的方法在

M icrosoft VC+ + 6. 0 平臺上運行通過(VC+ + 6. 0 AppW izard 生成M FC AppW izard (exe) 工程, 選用

DocumentöV iew 支持, 視圖基類選用CScrollV iew )

參考文獻:

[ 1 ] David J. Kruglinski. Programm ing V isual C+ + 6. 0 技術內幕(第五版) [M ] . 北京: 北京希望電子出版社, 19991

[ 2 ] 周長發1 精通V isual C+ + 圖像編程[M ] . 北京: 電子工業出版社, 20001

[ 3 ] John E. Swanke. VC+ + M FC Extensitons by Examp le[M ] . 北京: 機械工業出版社, 20001

[ 4 ] 劉厲, 周家紀1 位圖拼移技術在批量圖形處理中的應用[J ] . 物探化探計算技術, 2001, 23 (2) : 1761

[ 5 ] 李火亙, 周家紀1 設備場境化在W indow s GD I 中的應用[J ] . 物探化探計算技術, 1998, 20 (1) : 761

作者簡介: 張 弦(1976) , , 中國地質大學(武漢) 地球化學碩士研究生, 研究方向: 計算地球化學,

球物質組構的數值圖像處理。

1 期朱 劍等: 統一建模語言UML 及應用實例·95·__

 
發佈了6 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章