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

VC++ 顯示 BMP 圖片的三種主流方法對比與代碼範例

     編輯:VC 教學

在 VC++ 中動態顯示 BMP 圖片主要有三種途徑:資源嵌入、檔案載入 (GDI)、記憶體數據直接繪製 (DIB)。本文以 320×240 256 灰階圖為例,對比三種方法的優劣與適用場景,提供可直接複製的代碼片段。

方法一:嵌入資源 (最簡單、最不靈活)

  • 資源檔 .rc 加入 BMP,ID 為 IDB_MYIMAGE。
  • CBitmap bmp; bmp.LoadBitmap(IDB_MYIMAGE);
  • 優點:無外部依賴、部署簡單。缺點:EXE 膨脹、無法運行時切換圖片、佔用資源段記憶體。

方法二:LoadImage 載入檔案 + BitBlt 繪製 (最通用、推薦)

支援 BMP/ICON/CUR,可選 LR_CREATEDIBSECTION 獲得可操作像素的 DIB Section。

// 1. 載入
HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, _T("pic.bmp"), IMAGE_BITMAP, 0, 0,
                                    LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (!hBmp) return;

// 2. 繪製到視窗 DC
CDC* pDC = GetDC();
CDC memDC; memDC.CreateCompatibleDC(pDC);
CRect rect; GetClientRect(&rect);

HBITMAP hOld = (HBITMAP)memDC.SelectObject(hBmp);
// 伸縮繪製至客戶區 (或原尺寸 BitBlt)
pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, 320, 240, SRCCOPY);
// 或原尺寸: pDC->BitBlt(0,0,320,240,&memDC,0,0,SRCCOPY);

memDC.SelectObject(hOld);
memDC.DeleteDC();
ReleaseDC(pDC);
DeleteObject(hBmp); // 釋放 GDI 物件

灰階圖優勢: 內建調色盤,無需手動建立 RGBQUAD 表,LoadImage 自動處理。

方法三:記憶體像素陣列 + StretchDIBits / SetDIBitsToDevice (最高效、適用採集卡/即時影像)

適用場景:硬體採集卡回傳原始像素緩衝區 BYTE* pBuffer,無檔案頭,需手動構建 BITMAPINFOHEADER。

// 1. 構建 BITMAPINFO (含調色盤)
LPBITMAPINFO pBmi = (LPBITMAPINFO)new BYTE[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)];
pBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBmi->bmiHeader.biWidth = 320;
pBmi->bmiHeader.biHeight = -240; // 負值 = 自上而下 (Top-down DIB)
pBmi->bmiHeader.biPlanes = 1;
pBmi->bmiHeader.biBitCount = 8; // 256 灰階
pBmi->bmiHeader.biCompression = BI_RGB;
pBmi->bmiHeader.biSizeImage = 0;

// 灰階調色盤
for (int i=0; i<256; i++) {
    pBmi->bmiColors[i].rgbBlue = i;
    pBmi->bmiColors[i].rgbGreen = i;
    pBmi->bmiColors[i].rgbRed = i;
    pBmi->bmiColors[i].rgbReserved = 0;
}

// 2. 直接繪製到螢幕 DC (無需兼容 DC)
CDC* pDC = GetDC();
::StretchDIBits(pDC->m_hDC,
    10, 10, 640, 480,       // 目標矩形 (放大 2 倍)
    0, 0, 320, 240,         // 來源矩形
    pBuffer,                 // 像素指標
    pBmi, DIB_RGB_COLORS, SRCCOPY);

ReleaseDC(pDC);
delete[] pBmi;

方法對比總結

維度資源嵌入LoadImage 檔案記憶體 DIB
部署單一 EXE需攜帶圖片檔無檔案 (記憶體/串流)
運行時切換困難容易極易 (換指標)
效能一般良好最高 (零拷貝)
適用場景圖標、工具列固定圖片一般圖片瀏覽、報表即時影像、採集卡、視訊流
調色盤處理自動自動手動構建 (灰階簡單)

避坑指南

  • CBitmap::CreateBitmap 第三、四參數必須為 1,1 才能建立單色位圖,不適用於灰階/彩色,請改用 CreateDIBSection 或 LoadImage。
  • 所有 HBITMAP/HDC 用畢必須 DeleteObject/DeleteDC/ReleaseDC,否則 GDI 物件洩漏導致系統資源耗盡 (幾十秒內崩潰)。
  • biHeight 設負值表示 Top-down DIB,配合採集卡行序通常一致,避免影像上下翻轉。

根據專案需求選擇:固定資源用方法一,一般檔案用方法二,高效即時影像用方法三。

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