在VC中顯示和處理圖片的方法

法1:這個方法其實用的是一本經典vc圖像處理的書上的有關讀取位圖的函數庫,
當沒有這個函數庫時,就沒有太多的實用價值。
這種方法直接用的是讀取和顯示bmp圖片的函數庫
首先要得到要顯示區域的位置:
CWnd* pWnd=GetDlgItem(IDC_BMP);
RECT rect;
pWnd->GetClientRect(&rect);
CDC* pDC=pWnd->GetDC();
然后調用函數庫
//獲取DIB圖像的寬度
int cxDIB=(int)::DIBWidth(lpDIB);
//獲取DIB圖像的高度
int cyDIB=(int)::DIBHeight(lpDIB);
最后也是調用函數庫
//調用PaintDIB輸出圖像
::PaintDIB(pDC->m_hDC,&rect,m_hDIB,&rcDIB,NULL);
最要釋放資源
ReleaseDC(pDC);
--------------------------------------------------------------------------------
法2:
這種方法是直接在屏幕上畫圖,當然,由于是一點一點的畫的,所以,速度會慢些。
首先要得到要顯示區域的位置:
CWnd* pWnd=GetDlgItem(IDC_BMP);
CDC* pDC=pWnd->GetDC();
然后
pDC->SetPixel(iw,ih,RGB(r,g,b));
最要釋放資源
ReleaseDC(pDC);
------------------------------------------------------------------------------------
法3:
這種方法是在內存中開辟一個空間,然后也用SetPixel的方法往內存中寫數據,最后可以一次性地把數據顯示在屏幕上。當然,從描述上就知道,這種方法比法2要快些,但是,由于使用SetPixel,一個點一個點的寫數據,也會有些慢的。
首先要得到要顯示區域的位置:
CWnd* pWnd=GetDlgItem(IDC_BMP);
CDC* pDC=pWnd->GetDC();
然后
CDC memdc;
CBitmap m_bitmap,*m_pOldBitmap;
memdc.CreateCompatibleDC(pDC);
m_bitmap.CreateCompatibleBitmap(pDC,lWidth,lHeight);
m_pOldBitmap=memdc.SelectObject(&m_bitmap);
然后,就可以改變內存中的數據了
memdc.SetPixel(iw,lHeight-ih,RGB(nrgb,nrgb,nrgb));
將結果顯示出來
pDC->StretchBlt(0,0,rect.right-rect.left,rect.bottom-rect.top,&memdc,
0,0,lWidth,lHeight,SRCCOPY);
最后釋放資源
memdc.SelectObject(m_pOldBitmap);
m_bitmap.DeleteObject();
ReleaseDC(pDC);
-----------------------------------------------------------------------------------
法4:
這種方法挺不錯的,一定要好好看看:)
這應該是比法2和法3都快的方法了,因為其是直接在內存中分配一個區域,直接用操作內存區域的方法去操作它,等操作完成后在一次寫到屏幕上。
首先,得到要顯示的區域
CWnd* pWnd=GetDlgItem(IDC_IMG);
CDC *theDC=pWnd->GetDC();
CRect clientRect;
pWnd->GetClientRect(clientRect);
然后,寫頭文件
BITMAPINFOHEADER bmiHeader;
bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiHeader.biWidth = m_width;
bmiHeader.biHeight = m_height;
bmiHeader.biPlanes = 1;
bmiHeader.biBitCount = 24;
bmiHeader.biCompression = BI_RGB;
bmiHeader.biSizeImage = 0;
bmiHeader.biXPelsPerMeter = 0;
bmiHeader.biYPelsPerMeter = 0;
bmiHeader.biClrUsed = 0;
bmiHeader.biClrImportant = 0;
現在就可以顯示出圖像數據在屏幕上了
// now blast it to the CDC passed in.
// lines returns the number of lines actually displayed
int lines = StretchDIBits(theDC->m_hDC,
left, top,
bmiHeader.biWidth,
bmiHeader.biHeight,
0,0,
bmiHeader.biWidth,
bmiHeader.biHeight,
tmp,
(LPBITMAPINFO)&bmiHeader,
DIB_RGB_COLORS,
SRCCOPY);
注意呀,其中的tmp的類型是BYTE* ,也就是說其是指向一塊內存區首地址,只要這塊內存區中放的數據是BMP位圖中的數據區的格式,就可以了。也就是說每行元素都是32 bit(4 byte)的整數倍。
有了這種方法,可以說,可以直接用分配內存的函數先分配一個內存區域,然后,用memcpy將一個內存中的內容復制到另一個內存中,對其處理后,再顯示出來。
最后別忘了釋放資源
ReleaseDC(theDC);
------------------------------------------------------------------------
另外,獲得整個對話框的CDC,不好意思,不知道CDC是什么
CPaintDC dc(this);
CDC *theDC=&dc;