有三個函數可以完畢這一功能函數
1.BitBlt
BitBlt 用於從原設備中複製位圖到目標設備
post
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方法能夠延伸或收縮位圖以適應目標區域的大小
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);//選中位圖對象 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函數實現spa
該函數將DIB(設備無關位圖)中矩形區域內像素使用的顏色數據複製到指定的目標矩形中。假設目標設備是窗體DC,相贊成味着在窗體繪製位圖。code
StretchDIBits操做的是設備無關位圖是內存中的RGB數據,你必須告訴這個函數關於位圖的調色板、大小等信息,也就是位圖頭。對象
完畢功能:圖片
對話框程序,加入一個button。點擊button後顯示圖片內存
(1)設置BYTE*m_pBmpData爲類的成員變量,咱們要把圖片的RGB數據裝進去。ci
(2)button的後臺代碼it
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。即直接將不要的點刪掉。