閱讀276 返回首頁    go 阿裏雲 go 技術社區[雲棲]


MFC 對話框Picture Control(圖片控件)中靜態和動態顯示Bmp圖片

        最近有同學問我如何實現MFC基於對話框在圖片控件中加載圖片?其實使用MFC顯示圖片的方法各種各樣,但是還是有些同學不知道怎樣顯示.以前在《數字圖像處理》課程中完成的軟件都是基於單文檔的程序,這裏介紹兩種在對話框picthre控件中顯示BMP圖片的最簡單基礎的方法.
       ~~方法可能並不完美,高手忽略,但是提供一種能運行的方法,希望對剛接觸這方麵知識的同學有所幫助.可能你覺得文章過於簡單或者有些過於詳細敘述(點到即可我並不反對),但也為哪些入門同學想想,當初自己也是一頭霧水.
一.靜態顯示bmp圖片
       
1.
創建MFC基於對話框程序,添加一個button1和picture控件,其中“資源視圖”中編輯picture控件ID為:IDC_STATIC_PIC.
        2.在"資源視圖"(如果沒有,視圖中可調用出來)中右鍵鼠標Dialog處,選擇"添加資源".在對話框中選擇Bitmap,點擊"導入",選擇本地bmp圖片(建議位圖放置在res文件夾中).它會添加一張IDB_BITMAP1圖片
.


        3.點擊button1按鈕,在生成的函數中添加如下代碼:

void CShowBmpDlg::OnBnClickedButton1()
{
	//從資源中加載圖片
	CBitmap bitmap;
	//加載指定位圖資源 Bmp圖片ID
	bitmap.LoadBitmap(IDB_BITMAP1);  
	//獲取對話框上的句柄 圖片控件ID
 	CStatic *p=(CStatic *)GetDlgItem(IDC_STATIC_PIC);  
	//設置靜態控件窗口風格為位圖居中顯示
	p->ModifyStyle(0xf,SS_BITMAP|SS_CENTERIMAGE); 
	//將圖片設置到Picture控件上
	p->SetBitmap(bitmap); 
}

        4.運行結果如下圖所示:
   
        5.總結
        通過上麵的截圖我們可以發現:該方法是通過資源ID來獲取BMP圖片的,所以我稱之為靜態的方法.同時,可能你見到過在添加Picture控件時修改其Type為Bitmap在通過image選擇ID的方法.但這裏是通過代碼來實現的,而且ModifyStyle函數的功能就相當於設置其屬性.

        ~~上圖很明顯的反應了它顯示圖片時,如果圖片尺寸超過控件size隻能顯示部分圖片.方法我隻敘述到這,需要你自己去嚐試.曾經在單文檔中顯示BMP圖片時,是通過重載onpaint事件,GetClientRect獲取尺寸調用StretchBlt(圖像可拉伸壓縮)實現(參照
前文).
        其實LoadBitmap函數已被LoadImage替代,該函數用於裝載圖標\光標\位圖.如下代碼所示可以實現同樣的效果,其中Rockies.bmp為本地文件,與程序相同文件夾.

void CShowBmpDlg::OnBnClickedButton1()
{
	//獲取對話框上圖片控件的句柄
	CStatic* pWnd = (CStatic*)GetDlgItem(IDC_STATIC_PIC); 
	//設置靜態控件窗口風格為位圖居中顯示
	pWnd->ModifyStyle(0xf,SS_BITMAP|SS_CENTERIMAGE);
	//顯示圖片
	pWnd->SetBitmap((HBITMAP)::LoadImage(NULL,
		_T("Rockies.bmp"),  //資源號或本地文件名
		IMAGE_BITMAP,       //裝載位圖 IMAGE_CURSOR光標 IMAGE_ICON圖標
        0,                  //寬度 0為默認大小
        0,                  //高度 像素為單位
        LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE));
}

二.動態加載bmp圖片
       
動態添加的方法一樣,隻是添加代碼如下(這結合我以前的代碼完成).主要的步驟是:
        1.先定義打開文件對話框,通過它獲取bmp圖片,其中dlg.DoMal()==IDOK表示按下確認按鈕,實現後麵操作.如果你學過C#就會發現它的OpenFileDialog控件與這個有些類似.

        2.然後,獲取讀取文件的路徑和後綴,確保其為bmp時執行讀取圖片信息,在"2.MFC-bmp圖片讀取保存"中,我曾詳細講述過如何讀取bmp圖片,這裏也是二進製讀取文件,讀取其文件頭(BITMAPFILEHEADER)、信息頭(BITMAPINFOHEADER)、獲取其位圖數據.
        3.最後顯示圖像到Picture控件中,並通過GetClientRect函數獲取矩形區域,顯示圖像.

void CShowBmpDlg::OnBnClickedButton1()
{
	//打開文件 定義四種格式的文件bmp gif jpg tiff
	CString filter;
	filter="所有文件(*.bmp,*.jpg,*.gif,*tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| GIF(*.gif)|*.gif| TIFF(*.tiff)|*.tiff||";
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,filter,NULL);          

	//按下確定按鈕 dlg.DoModal() 函數顯示對話框
	if( dlg.DoModal() == IDOK )
	{
		//打開對話框獲取圖像信息
		CString BmpName = dlg.GetPathName();     //獲取文件路徑名   如D:\pic\abc.bmp
		CString EntName = dlg.GetFileExt();      //獲取文件擴展名
		EntName.MakeLower();                     //將文件擴展名轉換為一個小寫字符

		if(EntName.Compare(_T("bmp")) == 0)
		{
			//定義變量存儲圖片信息
			BITMAPINFO *pBmpInfo;       //記錄圖像細節
			BYTE *pBmpData;             //圖像數據
			BITMAPFILEHEADER bmpHeader; //文件頭
			BITMAPINFOHEADER bmpInfo;   //信息頭
			CFile bmpFile;              //記錄打開文件

			//以隻讀的方式打開文件 讀取bmp圖片各部分 bmp文件頭 信息 數據
			if(!bmpFile.Open(BmpName, CFile::modeRead|CFile::typeBinary)) 
				return;
			if (bmpFile.Read(&bmpHeader,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
				return;
			if (bmpFile.Read(&bmpInfo,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
				return;
			pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
			//為圖像數據申請空間
			memcpy(pBmpInfo,&bmpInfo,sizeof(BITMAPINFOHEADER));
			DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;
			pBmpData = (BYTE*)new char[dataBytes];
			bmpFile.Read(pBmpData,dataBytes);
			bmpFile.Close();

			//顯示圖像
			CWnd *pWnd=GetDlgItem(IDC_STATIC_PIC); //獲得pictrue控件窗口的句柄
			CRect rect;
			pWnd->GetClientRect(&rect); //獲得pictrue控件所在的矩形區域
			CDC *pDC=pWnd->GetDC(); //獲得pictrue控件的DC
			pDC->SetStretchBltMode(COLORONCOLOR);
			StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,
				bmpInfo.biWidth,bmpInfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);
		}
	}
}

        運行程序顯示結果如下圖所示,點擊按鈕打開圖片,顯示圖片.
 
        總結:通過這個程序你可以很明顯的看到動態加載圖片由於是通過獲取picture控件矩形來顯示圖的,圖像被拉伸了.而且代碼很好的反應了如何獲取bmp圖像的方法.通過靜態的和動態的兩種方法講述.
       
~~最後希望該文章對大家有所幫助,如果文章中有錯誤或不足之處,還請海涵.
        (By:Eastmount 2014-5-21 夜2點半 原創CSDN https://blog.csdn.net/eastmount/)

        PS:《數字圖像處理》課程希望大家也可以學習下,你可以自己完成一個軟件,你將對圖像有更深的認識.以前我們要求實現的功能就包括:圖像載入保存、采樣量化、直方圖顯示、線性和非線性變換(對比度拉伸、圖像均衡化)、幾何運算(最近鄰差值和雙線性差值)、幾何變換(平移、反轉、旋轉)、圖像增強(平滑、銳化Laplacian等各種算子)、邊緣檢測、圖像編碼壓縮(Huffman編碼和遊程編碼)、圖像分割複原、二值圖像細化等功能.記得最蛋疼的是DICOM醫學圖像在Android顯示與處理花了很長時間才完成的.

最後更新:2017-04-03 08:26:12

  上一篇:go Visual Studio 2008項目中WinForm窗體圖標顯示為類圖標,隻能打開代碼而無法打開視圖問題解決
  下一篇:go andriod遊戲音效