77范文网 - 专业文章范例文档资料分享平台

VC数字图像处理编程(4)

来源:网络收集 时间:2019-04-01 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

{//判断图像数据是否为空;

AfxMessageBox(\图像数据不能为空,请首先读取图像数据!\return; }

lpDIBHdr=( BITMAPINFOHEADER *)GlobalLock(pDoc->m_hDIB);//得到图像的位图头信息

lpDIBBits=lpDIBHdr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);//获取保存图像像素值的缓冲区的指针; if(pDoc-> m_palDIB)

{//如果存在调色板信息,实现逻辑调色板;

OldPal=pDC-> SelectPalette(pDoc-> m_palDIB,TRUE); PDC->RealizePalette(); } else {

AfxMessageBox(\图像的调色板数据不能为空,请首先读取调色板信息!\return ; }

SetStretchBltMode(hDC,COLORONCOLOR); //显示图像

BSuccess=StretchDIBBits(hDC,0,0,pDoc-> m_sizeDoc.cx, pDoc-> m_sizeDoc.cy,

0, pDoc-> m_sizeDoc.cy,0, pDoc-> m_sizeDoc.cy, lpDIBBits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);

GlobalUnlock(pDoc->m_hDIB); If(OldPal)//恢复调色板;

PDC->SelectPalette(OldPal,FALSE); retrun; }

四、 小结

在本期讲座里我们主要介绍了如何操作灰度位图,它具有较强的代表性,同时为后续的图像处理编程的学习作了必要的准备工作,经过学习,对于如何操作其它类型的BMP格式的图像文件,可以达到举一反三的作用。 VC数字图像处理编程讲座之四

BMP图像显示的特效操作

上期讲座中我们主要讲述了BMP图像数据的存取、图像的显示和调色板的操作等内容,在上面的学习基础上,我们可以进一步深化,学习并掌握图像特效显

示技术。有了这种技术,可以用来在今后的项目开发中美化我们的软件界面,提高软件的视觉效果。在如今的商业软件中,几乎每一幅图像的显示都采用了图像特效显示,例如读者比较熟悉的Windows的屏幕保护程序就采用了各种各样的图像特效显示,使人感到眼花缭乱和耳目一新。专业图像处理软件更是提供了丰富的显示方式供用户使用,可以方便的在程序中实现图像的特效显示,如

PhotoShop 、Authorware等。本节主要介绍如何实现图像的浮雕、雕刻、百页窗、旋转、扫描、栅条、马赛克、和渐显渐隐显示等效果。通过这期讲座的学习,读者朋友们也可以自己动手制作拥有特效显示效果的软件了。

图像的显示我们讲过主要有BitBlt()、SetDIBitsToDevice()和

StretchDIBits()等函数。需要读者注意的是,在特效显示时,并不是每个显示函数都适宜,BitBlt()函数主要是用来显示设备无关位图(DDB),后两个函数用来显示设备无关位图(DIB)。由于我们讲座里处理的是设备无关位图,所以我们主要关心的是后两个函数的应用,其中SetDIBitsToDevice()使用起来较死板,远不如StretchDIBits()用的灵活,并且对大多数的特效显示无能为力,所以为了实现图像的特效显示效果,需要使用StretchDIBits ()函数来显示图像,具体什么原因,我想可能是微软在实现这些函数时使用的方法不同吧。这些函数如何使用,各个参数的含义,可以参考微软的MSDN。

实现图像的特殊效果的显示的基本思路是要么是操作图像的像素,要么是对图像分块按一定的方向或次序,分阶段的显示或擦除对应的图像块。对于第二种显示的思路,其中的要点是:1.划分图像块;2.确定图像块的操作次序;3.显示或清除对应的图像块;4.在两个连续显示的图像块之间插入一个固定的延迟。其中图像块的划分决定了图像的显示方式,图像块的显示顺序决定了显示的方向和细分的依据。不同的效果决定了不同的分块方法和显示次序,我们将在后面的各种特效显示中介绍如何分块和决定次序。为了使图像的显示过程明显的表现出来,实现显示的特效,就需要在图像块的依此显示中插入固定的延迟。也许读者朋友会想到利用sleep()函数或用Settime()来实现延迟,由于Windows是个基于消息的多任务操作系统,这些方法所产生的延迟时间对于图像的显示来说是不精确的,为了实现与机器无关的更精确的时间延迟,可以采用timeGetTime()函数来产生微秒级的延迟。使用这个函数时为了编译不产生错误,要在连接设置中引入\库,并要包含头文件\。这里我们首先给出一个延迟函数,它用来实现固定时间的延迟:

void DelayTime(DWORD time) {

DWORD BeginTime ,EndTime;

BeginTime=timeGetTime();//得到当前的系统时间、单位为微秒; do {

EndTime=TimeGetTime();//再次得到当前的系统时间; }

while((EndTime-BeginTime) }

一、操作位图的像素实现显示的特效

我们首先介绍直接操作图像中的像素的灰度值来实现图像显示的特效、这里我们主要介绍如何实现图像的浮雕和雕刻效果。经常看电视的朋友们不知注意到没有,有些电视连续剧在每集片头或片尾部分都有显示一些特殊效果的图像,比如前一阵子中央一套放的《长征》和《康熙王朝》,这些特效称为\图像的浮雕效果\和\图像的雕刻效果\,经过这些特效处理后的图像增强了观众们的视觉效果,它们看上去仿佛是使用3D技术作的,这也许就是为什么这种技术那么流行的原因吧。其实,我们完全可以用一些简单的数字图像处理算法来实现这些看似复杂高深的显示效果。下面以一个标准的Lena灰度图像为原图,给出了处理后的效果图,同时给出了VC开发平台上的部分实现源代码。

1.\浮雕\图像

\浮雕\图象效果是指图像的前景前向凸出背景。所谓的\浮雕\概念是指标绘图像上的一个像素和它左上方的那个像素之间差值的一种处理过程,为了使图像保持一定的亮度并呈现灰色,我在处理过程中为这个差值加了一个数值为128的常量。需要读者注意的是,当设置一个像素值的时候,它和它左上方的像素都要被用到,为了避免用到已经设置过的像素,应该从图像的右下方的像素开始处理,下面是实现的源代码:

void CDibView::OnFDImage() //产生\浮雕\效果图函数 {

HANDLE data1handle;//用来存放图像数据的句柄; LPBITMAPINFOHEADER lpBi;//图像的信息头结构; CDibDoc *pDoc=GetDocument();//得到文挡指针; HDIB hdib;//用来存放图像数据的句柄;

unsigned char *pData;//指向原始图像数据的指针; unsigned char *data;//指向处理后图像数据的指针;

hdib=pDoc->m_hDIB;//拷贝存放已经读取的图像文件数据句柄;

lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);//获取图像信息头 pData=(unsigned char*)FindDIBBits((LPSTR)lpBi);

//FindDIBBits是我定义的一个函数、根据图像的结构得到位图的灰度值数据、 pDoc->SetModifiedFlag(TRUE);

//设置文档修改标志为\真\、为后续的修改存盘作准备;

data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight); //声明一个缓冲区用来暂存处理后的图像数据;

data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);//得到该缓冲区的指针;

AfxGetApp()->BeginWaitCursor(); int i,j,buf;

for( i=lpBi->biHeight; i>=2; i--)//从图像右下角开始对图像的各个像素进

行\浮雕\处理;

for( j=lpBi->biWidth; j>=2; j--) {

//浮雕处理

buf=*(pData+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)-*(pData+(lpBi->biHeight-i+1)*WIDTHBYTES(lpBi->biWidth*8)+j-1)+128; if(buf>255) buf=255; if(buf<0)buf=0;

*(data+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)=(BYTE)buf; }

for( j=0; jbiHeight; j++) for( i=0; ibiWidth; i++)

//重新写回原始图像的数据缓冲区;

*(pData+i*WIDTHBYTES(lpBi->biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi->biWidth*8)+j); AfxGetApp()->EndWaitCursor();

pDoc->m_hDIB =hdib//将处理过的图像数据写回pDoc中的图像缓冲区; GlobalUnlock((HGLOBAL)hdib);//解锁、释放缓冲区; GlobalUnlock((HGLOBAL)data1handle); GlobalFree((HGLOBAL)hdib);

GlobalFree((HGLOBAL)data1handle); Invalidate(TRUE);//显示图像 }

2.\雕刻\图像

上面讲述了通过求一个像素和它左上方像素之间的差值并加上一个常数的方法生成\浮雕\效果的灰度图像,\雕刻\图像与之相反,它是通过取一个像素和它右下方的像素之间的差值并加上一个常数,这里我也取128,经过这样处理,就可以得到\雕刻\图像,这时候图像的前景凹陷进背景之中。同样需要读者注意的是为了避免重复使用处理过的图像像素,处理图像时要从图像的左上方的像素开始处理。实现代码如下:

void CDibView::OnDKImage() {

// TOD Add your command handler code here

HANDLE data1handle;//这里的内部变量与前面的含义一致、这里不再赘述; LPBITMAPINFOHEADER lpBi;

CDibDoc *pDoc=GetDocument(); HDIB hdib;

unsigned char *pData; unsigned char *data;

hdib=pDoc->m_hDIB;//拷贝图像数据的句柄;

lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib); pData=(unsigned char*)FindDIBBits((LPSTR)lpBi);

pDoc->SetModifiedFlag(TRUE);

data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight);//申请缓冲区;

data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);//得到新的缓冲去的指针; AfxGetApp()->BeginWaitCursor(); int i,j,buf;

for( i=0;i<=lpBi->biHeight-2; i++)//对图像的各个像素循环进行\雕刻\处理;

for( j=0;j<=lpBi->biWidth-2; j++) {

buf=*(pData+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+ j)-*(pData+(lpBi->biHeight-i-1)*WIDTHBYTES(lpBi->biWidth*8)+j+1)+128; //\雕刻\处理;

if(buf>255) buf=255; if(buf<0)buf=0;

*(data+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)=(BYTE)buf; }

for( j=0; jbiHeight; j++)

for( i=0; ibiWidth; i++) //重新将处理后的图像数据写入原始的图像缓冲区内; *(pData+i*WIDTHBYTES(lpBi->

biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi->biWidth*8)+j);

pDoc->m_hDIB =hdib//将处理过的图像数据写回pDoc中的图像缓冲区; GlobalUnlock((HGLOBAL)hdib);//解锁、释放缓冲区; GlobalUnlock((HGLOBAL)data1handle); GlobalFree((HGLOBAL)hdib);

GlobalFree((HGLOBAL)data1handle); Invalidate(TRUE);//显示图像 }

3.图像的旋转

根据图像像素的位置来调节该位置的灰度可以实现许多显示的特效,例如图像的镜像、翻转等。灰度图像旋转就是根据这一个思想实现的,它是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度,通常是指绕图像的中心以逆时针方向旋转。首先根据旋转的角度、图像对角线的长度计算旋转后的图像的最大宽度、高度,根据旋转后图象最大的宽度、高度生成新的缓冲区,假设图像的左上角为(left, top),右下角为(right, bottom),则图像上任意点(x, y)绕其中心(xcenter, ycenter)逆时针旋转angle角度后,新的坐标位置(x1, y1)的计算公式为:

xcenter = (width+1)/2+left; ycenter = (height+1)/2+top;

x1 = (x-xcenter) cosθ - (y - ycenter) sinθ+xcenter;

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库VC数字图像处理编程(4)在线全文阅读。

VC数字图像处理编程(4).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/561797.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: