VC编程实现灰度图像与彩色图像的相互转换Word文档下载推荐.docx
- 文档编号:7555484
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:15
- 大小:409.46KB
VC编程实现灰度图像与彩色图像的相互转换Word文档下载推荐.docx
《VC编程实现灰度图像与彩色图像的相互转换Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《VC编程实现灰度图像与彩色图像的相互转换Word文档下载推荐.docx(15页珍藏版)》请在冰点文库上搜索。
bmiHeader.biBitCount=24;
bmiHeader.biClrImportant=0;
bmiHeader.biClrUsed=0;
bmiHeader.biCompression=BI_RGB;
bmiHeader.biHeight=lpBi->
biHeight;
bmiHeader.biWidth=lpBi->
biWidth;
bmiHeader.biPlanes=1;
bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmiHeader.biXPelsPerMeter=0;
bmiHeader.biYPelsPerMeter=0;
bmiHeader.biSizeImage=WIDTHBYTES(lpBi->
biWidth*8)*lpBi->
biHeight*3;
file:
//data=hData;
intR,G,B,i,j;
data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->
biHeight*3);
//生成存储彩色图象数据的缓冲区
data=(unsignedchar*)GlobalLock((HGLOBAL)data1handle);
for(i=0;
ibiHeight;
i++)//实现灰度到彩色变换
for(j=0;
jbiWidth*8);
j++)
{
if(*(hData+i*WIDTHBYTES(lpBi->
biWidth*8)+j)<
=64)
{R=0;
G=(int)4*(*(hData+i*WIDTHBYTES(lpBi->
biWidth*8)+j));
B=255;
}
biWidth*8)+j)>
64
&
&
*(hData+i*WIDTHBYTES(lpBi->
=128)
{R=0;
G=255;
B=(int)4*(128-*(hData+i*WIDTHBYTES(lpBi->
}
128
&
=192)
{R=(int)4*(*(hData+i*WIDTHBYTES(lpBi->
biWidth*8)+j)-128);
G=255;
B=0;
}
192
=255)
{R=255;
G=(int)4*(255-*(hData+i*WIDTHBYTES(lpBi->
file:
//将生成的R、G、B分量存入目标缓冲区
*(data+i*WIDTHBYTES(lpBi->
biWidth*8)*3+j*3)=B;
biWidth*8)*3+j*3+1)=G;
biWidth*8)*3+j*3+2)=R;
}
GlobalUnlock((HGLOBAL)hdib);
GlobalUnlock(data1handle);
EndWaitCursor();
CClientDCpDC(this);
file:
//显示真彩色图像
StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi->
biWidth,lpBi->
biHeight,0,0,
lpBi->
biWidth,lpBi->
biHeight,data,m_pBMI,DIB_RGB_COLORS,
SRCCOPY);
deletem_pBMI;
}
VC++灰度位图处理
图像处理技术已经渗透到人类生活的各个领域并得到越来越多的应用,图像处理所涉及的图像格式有很多种,如TIF、JEMP、BMP等等,工程应用中经常要处理256级的灰度BMP图像,如通过黑白采集卡采集得到的图像。
BMP灰度图像作为Windows环境下主要的图像格式之一,以其格式简单,适应性强而倍受欢迎。
在进行图像处理时,操作图像中的像素值就要得到图像阵列;
经过处理后的图像的像素值存储起来;
显示图像时要正确实现调色板,结合这些问题,文章针对性的给出了操作灰度BMP图像时的部分函数实现代码及注释。
一、BMP位图操作
BMP位图包括位图文件头结构BITMAPFILEHEADER、位图信息头结构BITMAPINFOHEADER、位图颜色表RGBQUAD和位图像素数据四部分。
处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。
对于256级灰度图像每个像素用8bit表示颜色的索引值,这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。
在处理图像应用程序的文档类(CdibDoc.h)中声明如下宏及公有变量:
#defineWIDTHBYTES(bits)(((bits)+31)/32*4)//计算图像每行象素所占的字节数目
HANDLEm_hDIB;
//存放位图数据的句柄
CPalette*m_palDIB;
//指向调色板Cpalette类的指针
CSizem_sizeDoc;
file:
//初始化视图的尺寸
1、读取灰度BMP位图
根据BMP位图文件的结构,操作BMP位图文件读入数据,重载了文挡类的OnOpenDocument函数如下:
BOOLCDibDoc:
OnOpenDocument(LPCTSTRlpszPathName)
{
CFilefile;
CFileExceptionfe;
if(!
file.Open(lpszPathName,CFile:
modeRead|CFile:
shareDenyWrite,&
amp;
fe))
{
AfxMessageBox(&
quot;
文件打不开&
);
returnFALSE;
}//打开文件
DeleteContents();
//删除文挡
BeginWaitCursor();
BITMAPFILEHEADERbmfHeader;
//定义位图文件头结构
DWORDdwBitsSize;
HANDLEhDIB;
LPSTRpDIB;
BITMAPINFOHEADER*bmhdr;
//指向位图信息头结构的指针
dwBitsSize=file.GetLength();
//得到文件长度
if(file.Read((LPSTR)&
bmfHeader,sizeof(bmfHeader))!
=
sizeof(bmfHeader))
if(bmfHeader.bfType!
=0x4d42)file:
//检查是否为BMP文件
returnFALSE;
hDIB=(HANDLE):
GlobalAlloc(GMEM_MOVEABLE|
GMEM_ZEROINIT,dwBitsSize);
file:
//申请缓冲区
if(hDIB==0)
{
returnFALSE;
}
pDIB=(LPSTR):
GlobalLock((HGLOBAL)hDIB);
//得到申请的缓冲区的指针
if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!
dwBitsSize-sizeof(BITMAPFILEHEADER))
:
GlobalUnlock((HGLOBAL)hDIB);
hDIB=NULL;
}//读数据,包括位图信息、位图颜色表、图像像素的灰度值
bmhdr=(BITMAPINFOHEADER*)pDIB;
//为指向位图信息头结构的指针付值
:
if((*bmhdr).biBitCount!
=8)file:
//验证是否为8bit位图
m_hDIB=hDIB;
InitDIBData();
file:
//自定义函数,根据读入的数据得到位图的宽、高、颜色表
//来得到初始化视的尺寸、生成调色板
EndWaitCursor();
SetPathName(lpszPathName);
//设置存储路径
SetModifiedFlag(FALSE);
//设置文件修改标志为FALSE
returnTRUE;
2、灰度位图数据的存储
为了将图像处理后所得到的像素值保存起来,重载了文档类的OnSaveDocument函数,其具体实现如下:
OnSaveDocument(LPCTSTRlpszPathName)
BITMAPFILEHEADERbmfHdr;
//位图文件头结构
LPBITMAPINFOHEADERlpBI;
//指向位图信息结构的指针
DWORDdwDIBSize;
modeCreate|
CFile:
modeReadWrite|CFile:
shareExclusive,&
}//打开文件
BOOLbSuccess=FALSE;
lpBI=(LPBITMAPINFOHEADER):
GlobalLock((HGLOBAL)m_hDIB);
if(lpBI==NULL)
dwDIBSize=*(LPDWORD)lpBI+256*sizeof(RGBQUAD);
//PartialCalculation
DWORDdwBmBitsSize;
//BMP文件信息结构所占的字节数
dwBmBitsSize=WIDTHBYTES((lpBI-&
gt;
biWidth)*((DWORD)lpBI-&
biBitCount)) *lpBI-&
//存储时位图所有像素所占的总字节数
dwDIBSize+=dwBmBitsSize;
lpBI-&
biSizeImage=dwBmBitsSize;
//位图所有像素所占的总字节数
file:
//以下五句为文件头结构填充值
bmfHdr.bfType=0x4d42;
//文件为&
BMP&
类型
bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
//文件总长度
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI-&
biSize
+256*sizeof(RGBQUAD);
//位图数据距问件头的偏移量
file.Write((LPSTR)&
bmfHdr,sizeof(BITMAPFILEHEADER));
//写文件头
file.WriteHuge(lpBI,dwDIBSize);
//将位图信息(信息头结构、颜色表、像素数据)写入文件
:
GlobalUnlock((HGLOBAL)m_hDIB);
EndWaitCursor();
SetModifiedFlag(FALSE);
//backtounmodified
returnTRUE;
}
二、调色板的操作
灰度图像要正确显示,必须实现逻辑调色板和系统调色板,通过在主框架类中处理Windows定义的消息WM_QUERYNEWPALETTE、WM_PALETTECHANGED及视图类中处理自定义消息WM_DOREALIZE(该消息在主框架窗口定义如下:
#defineWM_REALIZEPAL(WM_USER+100))来实现调色板的操作。
voidCMainFrame:
OnPaletteChanged(CWnd*pFocusWnd)
{file:
//总实现活动视的调色板
CMDIFrameWnd:
OnPaletteChanged(pFocusWnd);
CMDIChildWnd*pMDIChildWnd=MDIGetActive();
if(pMDIChildWnd==NULL)
return
CView*pView=pMDIChildWnd-&
GetActiveView();
ASSERT(pView!
=NULL);
SendMessageToDescendants(WM_DOREALIZE,(WPARAM)pView-&
m_hWnd);
//通知所有子窗口系统调色板已改变
BOOLCMainFrame:
OnQueryNewPalette()//提供实现系统调色板的机会
//实现活动视的调色板
CMDIChildWnd*pMDIChildWnd=MDIGetActive();
if(pMDIChildWnd==NULL)
//noactiveMDIchildframe(nonewpalette)
CView*pView=pMDIChildWnd-&
ASSERT(pView!
//通知活动视图实现系统调色板
pView-&
SendMessage(WM_DOREALIZE,(WPARAM)pView-&
returnTRUE;
LRESULTCDibView:
OnDoRealize(WPARAMwParam,LPARAM)//实现系统调色板
ASSERT(wParam!
CDibDoc*pDoc=GetDocument();
if(pDoc-&
m_hDIB==NULL)
return0L;
//mustbeanewdocument
CPalette*pPal=pDoc-&
m_palDIB;
//调色板的颜色表数据在InitDIBData()函数中实现
if(pPal!
=NULL)
CMainFrame*pAppFrame=(CMainFrame*)AfxGetApp()-&
m_pMainWnd;
ASSERT_KINDOF(CMainFrame,pAppFrame);
CClientDCappDC(pAppFrame);
CPalette*oldPalette=appDC.SelectPalette(pPal,((HWND)wParam)!
=m_hWnd);
//只有活动视才可以设为&
FALSE&
,
//即根据活动视的调色板设为&
前景&
调色板
if(oldPalette!
{
UINTnColorsChanged=appDC.RealizePalette();
//实现系统调色板
if(nColorsChanged&
0)
pDoc-&
UpdateAllViews(NULL);
//更新视图
appDC.SelectPalette(oldPalette,TRUE);
file:
//将原系统调色板置为逻辑调色板
}
else
TRACE0(&
\tSelectPalettefailedin
CDibView:
OnPaletteChanged\n&
}
注:
在调用API函数显示位图时,不要忘记设置逻辑调色板,即&
背景&
调色板,否则位图将无法正确显示。
三、图像的数字化处理
通过以上读文件的操作,已经得到图像数据,由于得到的数据包括多余信息,所以在进行数字图像处理时要进一步删除多余信息,只对位图的像素进行操作,以基于模板的高通滤波为例来讲述数字图像处理的实现:
OnMENUHighPass()
{HANDLEdata1handle;
LPBITMAPINFOHEADERlpBi;
CDibDoc*pDoc=GetDocument();
HDIBhdib;
unsignedchar*hData;
unsignedchar*data;
hdib=pDoc-&
lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);
hData=(unsignedchar*)FindDIBBits((LPSTR)lpBi);
pDoc-&
SetModifiedFlag(TRUE);
data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 编程 实现 灰度 图像 彩色 相互 转换