BMP文件的讀取與顯示

有三個函數能夠完成這一功能函數

1.BitBlt   

BitBlt 用於從原設備中複製位圖到目標設備


this

void CMFCApplication1View::OnDraw(CDC* pDC)
{
	CMFCApplication1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CDC memDC;//定義一個設備上下文
	memDC.CreateCompatibleDC(pDC);//建立兼容的設備上下文
	CBitmap bmp;//定義位圖對象
	bmp.LoadBitmap(IDB_BITMAP1);//加載位圖
	memDC.SelectObject(&bmp);//選中位圖對象
	pDC->BitBlt(30, 20, 180, 180, &memDC, 1, 1, SRCCOPY);//繪製位圖
}


2.StretchBlt   


從源矩形中複製一個位圖到目標矩形,必要時按目標設備設置的模式進行圖像的拉伸或壓縮,若是目標設備是窗口DC,則意味着在窗口繪製位圖。
函數從源矩形中複製一個位圖到目標矩形,必要時按目標設備設置的模式進行圖像的拉伸或壓縮。也便是將內存中的位圖拷貝到屏幕上,而且能夠根據屏幕畫圖區的大小來進行伸縮,適應響應的屏幕(或圖像控件)


BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
x:邏輯單元x軸左上角座標; (獲取圖像控件的DC後,該值通常設爲 0 ) 
y:邏輯單元y軸左上角座標; (獲取圖像控件的DC後,該值通常設爲 0 ) 
nWidth: 設備矩形寬度;(便是圖像控件的寬度,經過int rcWidth = rc.right - rc.left;來得到,rc爲保存了圖像控件矩形區座標信息)
nHeight:設備矩形高度;  (便是圖像控件的高度,經過int rcHeight = rc.bottom - rc.top;來得到)
pSrcDC: 源設備上下文;   (就是咱們定義的內存DC,而後取地址)
xSrc :源矩形x軸左上角座標;   (通常都是整幅圖片拷貝,因此該值爲 0 )
ySrc: 源矩形y軸左上角座標;  (通常都是整幅圖片拷貝,因此該值爲 0 )
Specifies the x-coordinate (in logical units) of the upper-left corner of the source rectangle.
nSrcWidth:源矩形寬度;(若是咱們定義了一個結構體BITMAP類型m_bmp保存位圖信息,那麼能夠用m_bmp.bmWidth獲取寬度)
nSrcHeight:源矩形高度 ( 若是咱們定義了一個結構體BITMAP類型m_bmp保存位圖信息,那麼能夠用m_bmp.bmHeight獲取寬度)
dwRop:指定要進行的光柵操做。(這個有不少選擇,咱們通常選擇SRCCOPY:將源矩形區域直接拷貝到目標矩形區域。)


StretchBlt與BitBlt不一樣在於StretchBlt方法可以延伸或收縮位圖以適應目標區域的大小

spa

void CMFCApplication1View::OnDraw(CDC* pDC)
{
	CMFCApplication1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	CDC memDC;//定義一個設備上下文
	memDC.CreateCompatibleDC(pDC);//建立兼容的設備上下文
	CBitmap bmp;//定義位圖對象
	bmp.LoadBitmap(IDB_BITMAP1);//加載位圖
	memDC.SelectObject(&bmp);//選中位圖對象
	CRect rc(30, 20, 210, 200);//定義一個區域
	CBrush brush(RGB(0, 0, 0));//定義一個黑色的畫刷
	pDC->FrameRect(rc, &brush);//繪製矩形邊框
	//只是用來觀察二者區別的,繪製一個矩形框
	rc.OffsetRect(220, 0);//移動區域
	//下邊是利用StretchBlt繪製的位圖
	BITMAP BitInfo;//定義位圖結構
	bmp.GetBitmap(&BitInfo);//獲取位圖信息
	int x = BitInfo.bmWidth;//獲取位圖寬度
	int y = BitInfo.bmHeight; //獲取位圖高度
	pDC->StretchBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memDC, 0, 0, x, y, SRCCOPY);//繪製位圖
	pDC->FrameRect(rc, &brush);//繪製邊框
	brush.DeleteObject();//釋放畫刷
	memDC.DeleteDC();//釋放設備上下文
	bmp.DeleteObject();//釋放位圖對象
}




3.StretchDIBits函數實現code

該函數將DIB(設備無關位圖)中矩形區域內像素使用的顏色數據拷貝到指定的目標矩形中,若是目標設備是窗口DC,一樣意味着在窗口繪製位圖。
對象


StretchDIBits操做的是設備無關位圖是內存中的RGB數據,你必須告訴這個函數關於位圖的調色板、大小等信息,也就是位圖頭。圖片


完成功能:內存

對話框程序,添加一個按鈕,點擊按鈕後顯示圖片ci


(1)設置BYTE*m_pBmpData爲類的成員變量,咱們要把圖片的RGB數據裝進去。it


(2)按鈕的後臺代碼io


void Cbmp_readDlg::OnBnClickedShowbmp()
{
	CFile file;								//定義一個文件對象
	file.Open(CString("C:\\Users\\jian\\Desktop\\z.bmp"), CFile::modeRead);//打開文件
	DWORD  dwLen = file.GetLength();					//獲取文件長度
	file.Seek(14, CFile::begin);						//略過位圖文件頭
	if (m_pBmpData != NULL)
	{
		delete[] m_pBmpData;
		m_pBmpData = NULL;
	}
	m_pBmpData = new BYTE[dwLen - 14];					//爲緩衝區分配空間
	file.Read(m_pBmpData, dwLen - 14);					//讀取文件數據到緩衝區
	file.Close();								//關閉文件
	OnPaint();
}

(3)重寫OnPaint函數


void Cbmp_readDlg::OnPaint()
{
	/*******************分隔線之間的代碼自動生成的,不用管************************/
	if (IsIconic())
	{
		CPaintDC dc(this); // 用於繪製的設備上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使圖標在工做區矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 繪製圖標
		dc.DrawIcon(x, y, m_hIcon);
	}

	/*******************分隔線之間的代碼自動生成的,不用管。下面是添加的代碼************************/
	else
	{
		if (m_pBmpData != NULL)
		{
			BYTE *pHeader = m_pBmpData;			//定義一個臨時緩衝區
			BITMAPINFO BitInfo;			        //定義位圖信息對象
			memset(&BitInfo, 0, sizeof(BITMAPINFO));	//初始化位圖信息對象
			memcpy(&BitInfo, pHeader, sizeof(BITMAPINFO));	//爲位圖信息對象賦值
			int nWidth = BitInfo.bmiHeader.biWidth;		//獲取位圖寬度
			int nHeight = BitInfo.bmiHeader.biHeight;	//獲取位圖高度
			pHeader += 40;					//指向位圖數據
			//輸出位圖信息,這裏完成顯示
			StretchDIBits(GetDC()->m_hDC, 10, 40, nWidth, nHeight, 0, 0, nWidth, nHeight,
				pHeader, &BitInfo, DIB_RGB_COLORS, SRCCOPY);
		}
		CDialogEx::OnPaint();
	}
}


SetStretchBltMode 當用StretchBlt縮小時,咱們常常發現它會失真:其緣由爲當StrecthBlt() 的DestRect比SrcRECT小時 必須要將一些點去掉,他的預設作法 是將要去掉的點與旁邊的點作AND運算,因此致使像素錯誤,在調用StretchBlt以前使用SetStretchBltMode函數,該函數能夠設置指定設備環境中的位圖拉伸模式, int SetStretchBltMode(HDC hdc, int iStretchMode) iStretchMode通常選用COLORONCOLOR,即直接將不要的點刪掉。

相關文章
相關標籤/搜索