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

VC++ 使用 OLE IPicture 介面顯示 JPG/GIF 圖片

     編輯:VC 教學

動機

MFC 僅原生支援 BMP。JPG/GIF 壓縮率高、檔案小,適合資源嵌入或外部載入。利用系統內建 OleLoadPicture + IPicture COM 介面可零第三方庫顯示。

核心介面與函數

// 從 IStream 載入圖片
HRESULT OleLoadPicture(
    IStream* pStream,   // 包含圖片資料的流
    LONG lSize,         // 讀取位元組數
    BOOL fRunmode,      // TRUE=執行模式
    REFIID riid,        // IID_IPicture
    void** ppvObj       // 輸出 IPicture**
);

// IPicture::Render 繪製到 DC
HRESULT Render(
    HDC hdc, long x, long y, long cx, long cy,
    OLE_XPOS_HIMETRIC xSrc, OLE_YPOS_HIMETRIC ySrc,
    OLE_XSIZE_HIMETRIC cxSrc, OLE_YSIZE_HIMETRIC cySrc,
    const RECT* pRcWBounds); // 目標矩形 (HIMETRIC 單位),NULL 為預設

完整實作流程 (OnDraw 中)

  1. 選取檔案:CFileDialog 篩選 *.jpg;*.gif,取得路徑 m_strPath。
  2. 開啟檔案建立 IStream:
    CFile file; CFileStatus fs;
    if (file.Open(m_strPath, CFile::modeRead) && file.GetStatus(fs) && fs.m_size > 0) {
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, fs.m_size);
        LPVOID pData = GlobalLock(hGlobal);
        file.ReadHuge(pData, fs.m_size);
        GlobalUnlock(hGlobal);
        IStream* pStream = NULL;
        CreateStreamOnHGlobal(hGlobal, TRUE, &pStream); // TRUE: 釋放時自動 Free hGlobal
    }
  3. 載入 IPicture:
    IPicture* pPic = NULL;
    HRESULT hr = OleLoadPicture(pStream, fs.m_size, TRUE, IID_IPicture, (void**)&pPic);
    pStream->Release(); // OleLoadPicture 內部 AddRef,這裡 Release 平衡
    if (FAILED(hr) || !pPic) { AfxMessageBox(_T("載入失敗")); return; }
  4. 計算繪製尺寸 (HIMETRIC → 像素):
    long hmW, hmH;
    pPic->get_Width(&hmW); pPic->get_Height(&hmH); // 单位: 0.01 mm (HIMETRIC)
    
    int scrW = pDC->GetDeviceCaps(HORZRES);  // 螢幕寬像素
    int scrH = pDC->GetDeviceCaps(VERTRES);
    int scrMMW = pDC->GetDeviceCaps(HORZSIZE); // 螢幕寬毫米
    int scrMMH = pDC->GetDeviceCaps(VERTSIZE);
    
    double pixW = (double)scrW * hmW / (scrMMW * 100.0); // HIMETRIC=0.01mm
    double pixH = (double)scrH * hmH / (scrMMH * 100.0);
  5. 繪製:
    HRESULT hr = pPic->Render(pDC->m_hDC, 0, 0, (long)pixW, (long)pixH,
                              0, hmH, hmW, -hmH, NULL); // ySrc=hmH, cySrc=-hmH 翻轉 Y 軸 (GDI 原點左上,HIMETRIC 原點左下)
    if (FAILED(hr)) AfxMessageBox(_T("繪製失敗"));
    pPic->Release();

關鍵細節

  • OleLoadPicture 支援 BMP/JPG/GIF/ICO/WMF/EMF 等系統註冊解碼器格式。
  • Y 軸翻轉:ySrc = hmHeight, cySrc = -hmHeight 修正座標系差異。
  • 記憶體管理:CreateStreamOnHGlobal(..., TRUE) 讓流負責釋放 HGLOBAL;IPicture 需手動 Release。
  • 錯誤處理:所有 COM 呼叫檢查 SUCCEEDED/FAILED。

優缺點

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
優點缺點
零第三方依賴,系統內建需初始化 COM (AfxOleInit 或 CoInitialize)
支援常見壓縮格式大圖載入較慢 (無快取/解碼控制)
程式碼簡潔無法存取像素級資料、無動畫支援 (GIF 僅顯示第一幀)