在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;