有三個函數能夠完成這一功能函數
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(); }
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,即直接將不要的點刪掉。