1. 程式人生 > >MFC 對話方塊Picture Control(圖片控制元件)中靜態和動態顯示Bmp圖片

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影象的方法.通過靜態的和動態的兩種方法講述.
       
~~最後希望該文章對大家有所幫助,如果文章中有錯誤或不足之處,還請海涵.
        )

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