首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

在 MFC 應用程式中顯示 JPG/GIF 圖片檔案

     編輯:關於VC++

若你是 Visual Basic 程式設計師,在程式中顯示 JPG 或 GIF 圖片輕而易舉,拖拉圖片控制項到表單即可。但 C++ 程式設計師要顯示相同格式圖片卻沒那麼輕鬆,難道要自己撰寫 JPG 解壓縮程式碼?當然不需要那麼複雜!本範例將探討如何在 MFC 中顯示 JPG 或 GIF 格式圖片檔案。

實現方法

Visual Basic 之所以輕鬆,是因為利用了豐富的圖片處理控制項,它們處理了顯示圖片檔案的所有底層工作。其實 C/C++ 程式設計師也能使用那些 Visual Basic 所用的(或幾乎相同的)圖片控制項。Visual Basic 使用的圖片控制項實際上都基於一個系統級 COM 類別 IPicture。以下是 IPicture 類別的主要方法:

  • get_Handle():傳回圖片物件的 Windows GDI 控制代碼
  • get_Hpal():傳回圖片物件目前使用的調色盤副本
  • get_Type():傳回目前圖片物件的圖片類型
  • get_Width() / get_Height():傳回圖片寬度/高度
  • Render():在指定位置、指定裝置內容上繪製指定圖片部分
  • set_Hpal():設定目前圖片的調色盤
  • get_CurDC():傳回目前選中此圖片的裝置內容
  • SelectPicture():將一個點陣圖選入給定裝置內容,傳回選中圖片的裝置內容與 GDI 控制代碼
  • get_KeepOriginalFormat() / put_KeepOriginalFormat():取得/設定 KeepOriginalFormat 屬性
  • PictureChanged():通知圖片物件其資源已改變
  • SaveAsFile():將圖片資料儲存至串流,格式與存檔相同
  • get_Attributes():傳回圖片位屬性目前設定

從上述方法可見,IPicture 操控著圖片物件及其屬性。圖片物件提供點陣圖的抽象層,而 Windows 負責 BMP、JPG、GIF 等格式的標準實作。程式設計師只需實例化 IPicture 物件,然後呼叫其 Render() 函數。與一般使用介面方式不同,這裡建立實例不使用 CoCreateInstance(),而是使用專門函數 OleLoadPicture(),具體程式碼如下:

IStream* pstm = // 需要一個串流
IPicture* pIPicture;
hr = OleLoadPicture(pstm, 0, FALSE, IID_IPicture, (void**)&pIPicture);

OleLoadPicture() 從資料串流載入圖片並建立可用於顯示圖片的新 IPicture 物件。IPicture 負責處理所有瑣事,自動判斷圖片格式(Windows 點陣圖、JPEG、GIF、甚至圖示與中繼檔)。所有實作細節都需要技巧,本範例撰寫了 Demo 程式 Myimgapp 示範 IPicture 的使用方法。Myimgapp 是典型的 MFC 文件/視圖程式,編寫前先對 IPicture COM 介面進行封裝,主要考量並非每位程式設計師都熟練 COM 程式設計,且將功能封裝在 C++ 類別中能讓問題更易解決。封裝的類別命名為 CPicture,定義與實作細節請參考本文提供的原始碼。

CPicture 將複雜陌生的 COM 風格參數對應為 MFC 程式設計師更熟悉的類型。例如,可直接從檔名、CFile 或 CArchive 載入圖片,無需處理串流。CPicture::Render() 替你完成 IPicture 中所有繁瑣但必要的 HIMETRIC 單位轉換工作。CPicture 甚至具備 Load() 函數,可從資源資料載入圖片,只需以下程式碼即可顯示資源中的圖片:

CPicture pic(ID_MYPIC); // 載入圖片
CRect rc(0,0,0,0); // 使用預設 rc
pic.Render(pDC, rc); // 顯示圖片

CPicture::Render 提供顯示圖片的矩形區域。IPicture 會對圖片進行延伸處理。若傳遞空矩形,CPicture 會使用圖片原始大小不進行延伸。對於圖片資源,CPicture 查找 "IMAGE" 類型資源,因此在資源檔中必須加入如下陳述式:IDR_MYPIC IMAGE MOVEABLE PURE "res\MyPic.jpg"。

CPicture 是個優秀的「傻瓜類別」,擁有指向 IPicture 介面的 ATL 智慧指標 CComQIPtr,透過呼叫 OleLoadPicture 初始化不同的 Load 函數。CPicture 提供常用封裝函數呼叫底層 IPicture,僅封裝 Demo 範例所需方法。若讀者需呼叫 IPicture::get_Handle 或其他較少用的方法,可自行嘗試撰寫對應封裝程式碼。

總之,IPicture/CPicture 簡化了圖片顯示,甚至能處理調色盤識別這類複雜處理,讀者完全可拋棄傳統 DIB 繪圖方法(載入調色盤、BitBlt()、StretchBlt() 等操作)——這一切 IPicture 全能搞定。

程式中有個訊息處理器值得一提:視圖類別的 OnEraseBkgnd() 函數。當顯示的圖片小於客戶區時,此函數必須繪製空白區域。它會建立與圖片大小相等的裁切矩形,再將客戶區填滿黑色。建立裁切矩形主要是避免視窗大小改變時出現閃爍——FillRect() 不會繪製裁切矩形內區域,這是 Windows 圖形處理常識。

程式設計步驟

  1. 啟動 Visual C++ 6.0,建立單一文件視圖結構應用程式,視圖類別基類為 CScrollView,專案命名為 "Myimgapp"。
  2. 在專案程式碼中加入 "CPicture" 類別;工具列加入圖片顯示比例按鈕,細節參考程式碼。
  3. 使用資源編輯器向程式加入 JPEG 格式圖片資源。
  4. 加入程式碼,編譯執行程式。

程式碼重點

本文提供完整的 CPicture 類別定義與實作,以及 CPictureView 視圖類別的完整程式碼,包含捲軸處理、縮放功能、背景清除等核心邏輯。完整程式碼請參考本文附帶原始碼。

小結

本範例透過 CPicture 類別實現 JPEG 圖片顯示,讀者可直接用於多媒體應用程式開發。此外,MFC 提供現成類別 CPictureHolder,功能幾乎與 CPicture 完全相同,定義位於 afxctl.h 中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved