《最新图像的存取、显示与生成精品课件.ppt》由会员分享,可在线阅读,更多相关《最新图像的存取、显示与生成精品课件.ppt(33页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、24.1.3 CImage类类(1)lCImage是是Visual C+中中MFC的一个类的一个类CImage类使图形、图像软件的开发跨越了类使图形、图像软件的开发跨越了DDB与与DIB概念,概念,使处理更为简洁、方便使处理更为简洁、方便 CImage类提供了读入和保存类提供了读入和保存BMP、JPEG、GIF、TIF与与PNG等格式图像的能力等格式图像的能力CImage可以直接使用可以直接使用Windows提供的图形功能提供的图形功能 94.1.5 图像文件的输入与输出图像文件的输入与输出lCImage类类读入读入图象数据的成员函数图象数据的成员函数:HRESULT Load( LPCTST
2、R pszFileName ) throw( ); 例如:例如:WorkCanvus.Load(m_FileName);lCImage类类保存保存图象数据的成员函数图象数据的成员函数:HRESULT Save( IStream* pStream, REFGUID guidFileType ) const throw(); 10读入图象文件并显示图象的步骤读入图象文件并显示图象的步骤l(1)建立建立CImage对象,例如对象,例如WorkCanvusl(2)在在“打开文件打开文件”菜单处理程序菜单处理程序OnFileOpen()函数中用函数中用WorkCanvus的的Load()成员函数将图像文
3、件里的图象数据读入成员函数将图像文件里的图象数据读入到到WorkCanvus中中l(3)在菜单在菜单“显示工作画布显示工作画布”处理程序处理程序OnDisplayWorkcanvus()中用中用WorkCanvus的的Bitblt()函数将函数将WorkCanvus中的图象数据中的图象数据传送到画布(例如传送到画布(例如CClientDC或或pDC)上)上WorkCanvus图像文件图像文件Load()Bitblt()画布画布11打开图像文件打开图像文件-OnFileOpen()l菜单菜单: “文件文件/打开打开” l源文件:源文件:CImageDoc.cppl函数:函数:OnFileOpen
4、()l步骤步骤:(1)添加添加CImage类的类的全局对象全局对象WorkCanvus,并在并在stdafx.h中将中将WorkCanvus说明为说明为外部对象外部对象extern CImage WorkCanvus;(2)添加添加CImageDoc类的事件类的事件ID_FILE_OPEN的处理函数的处理函数 void CImageDoc:OnFileOpen()(3)在在CImageDoc:OnFileOpen()函数中编写程序函数中编写程序由对话框输入图像文件名由对话框输入图像文件名根据文件名从图像文件中读入图像数据到根据文件名从图像文件中读入图像数据到CImage类的对象类的对象Work
5、Canvus中中并设置最近打开的文件名并设置最近打开的文件名12Program CImageDoc.cpp OnFileOpen()void CImageDoc:OnFileOpen()。CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, strFilter);hResult = (int)dlg.DoModal();/由对话框输入图像文件名由对话框输入图像文件名m_FileName = dlg.GetFileName();/保存当前文件名保存当前文件名hResult = WorkCanvus.Load(m_FileName);/根据文件名
6、从图像文件中读根据文件名从图像文件中读入图像数据到入图像数据到CImage类的对象类的对象WorkCanvus中中SetPathName(m_FileName,1);/设置最近打开的文件名设置最近打开的文件名UpdateAllViews(NULL);/调用调用OnDraw显示图象显示图象13保存图像文件保存图像文件(1)l菜单菜单: “文件文件/另存为另存为” l源文件:源文件:CImageDoc.cppl函数:函数:OnFileSaveAs()l步骤步骤:(1)添加添加CImageDoc类的事件类的事件ID_FILE_SAVE_AS的处理函数的处理函数void CImageDoc:OnFil
7、eSaveAs()(3)在在CImageDoc: OnFileSaveAs()函数中编写程序:函数中编写程序:由对话框输入图像文件名由对话框输入图像文件名根据文件名将根据文件名将CImage类的对象类的对象WorkCanvus中的图像数据中的图像数据保存到图像文件中去保存到图像文件中去14保存图像文件保存图像文件(2)void CImageDoc:OnFileSaveAs()CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,strFilter);hResult = (int
8、)dlg.DoModal();/ 由对话框输入文件名由对话框输入文件名hResult = WorkCanvus.Save(strFileName);15显示显示CImage类对象中的图象类对象中的图象l菜单菜单: “画布操作画布操作/显示工作画布显示工作画布” l源文件:源文件:CImageView.cppl函数:函数:OnDisplayWorkcanvus()void DrawWorkCanvus(CDC *pDC) CClientDCdc(this);intnXDest,nYDest,nWidth,nHeight,nXSrc,nYSrc;nXSrc=0;nYSrc=0;nXDest=0;n
9、YDest=0;nWidth=WorkCanvus.GetWidth();nHeight=WorkCanvus.GetHeight();WorkCanvus.BitBlt(dc,nXDest,nYDest,nWidth,nHeight,nXSrc,nYSrc,SRCCOPY);164.2 画布画布l画布是一个将图像作为二维像素数组存储的数据结构画布是一个将图像作为二维像素数组存储的数据结构屏幕画布屏幕画布n屏幕上屏幕上Windows窗口中的客户区窗口中的客户区n可通过新建可通过新建CClientDC的对象来创建屏幕画布的对象来创建屏幕画布n利用利用OnDraw()函数中的参数函数中的参数pDC
10、来创建屏幕画布来创建屏幕画布内存画布内存画布n建立一个或多个建立一个或多个CImage对象来创建内存画布对象来创建内存画布l画布可用作双缓存技术画布可用作双缓存技术克服屏幕画面的闪烁克服屏幕画面的闪烁174.2.1-2 CImage对象的创建对象的创建BOOL Create(int nWidth, int nHeight,int nBPP,DWORD dwFlags=0)throw();lnWidth The width of the CImage bitmap, in pixels. lnHeight The height of the CImage bitmap, in pixels. I
11、f nHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower left corner. If nHeight is negative, the bitmap is a top-down DIB and its origin is the upper left corner. lnBPP The numbers of bits per pixel in the bitmap. Usually 4, 8, 16, 24, or 32. Can be 1 for monochrome bitmaps
12、or masks. ldwFlags Specifies if the bitmap object has an alpha channel. Can be a combination of zero or more of the following values:184.2.1-3 CImage对象转换成对象转换成CDC对象对象 lCDC中有大量绘图函数,那么如何用中有大量绘图函数,那么如何用CDC类的成员函数在类的成员函数在CImage对象上绘图?对象上绘图?l从从CImage对象取得对象取得HDC设备描述表,再转换成设备描述表,再转换成CDC对象,对象,l例如例如 CImage Work
13、Canvus;CDC*pDC; pDC=CDC:FromHandle(WorkCanvus.GetDC();/获取获取CDC指针指针 pDC-SetPixel(x,y,(COLORREF) n); /CDC上的各种绘图操作上的各种绘图操作 WorkCanvus.ReleaseDC(); / 释放释放HDC194.2.2 窗口刷新窗口刷新 lWindows通过调用通过调用OnDraw()函数刷新窗口函数刷新窗口 l何时需要刷新窗口?何时需要刷新窗口?系统需要,例如系统改变窗口的尺寸系统需要,例如系统改变窗口的尺寸程序需要,例如程序要重画,可调用程序需要,例如程序要重画,可调用Invalidate
14、()使窗口失使窗口失效效Invalidate()可以使整个窗口失效进行重绘,也可定义一可以使整个窗口失效进行重绘,也可定义一个矩形区域只使一个区域内部某些地方失效个矩形区域只使一个区域内部某些地方失效l刷新时全部清除失效区域后,再重新开始绘制新的画面,故在刷新时全部清除失效区域后,再重新开始绘制新的画面,故在执行过程中会看到屏幕有一次闪动执行过程中会看到屏幕有一次闪动 l刷新窗口的方法刷新窗口的方法重新绘制,即将形成当前图像画面的过程再重复一遍重新绘制,即将形成当前图像画面的过程再重复一遍备份复贴,即将当前的屏幕画面存储起来作为备份,刷新时备份复贴,即将当前的屏幕画面存储起来作为备份,刷新时将
15、备份粘贴到屏幕上将备份粘贴到屏幕上204.2.3 演示程序中一些画布的设置演示程序中一些画布的设置l工作画布工作画布-用于存放需要进行处理的图像用于存放需要进行处理的图像CImage对象,名为对象,名为WorkCanvusl副本画布副本画布-保存图像,必要时把副本画布恢复到工作画布中去保存图像,必要时把副本画布恢复到工作画布中去CImage对象,名为对象,名为SaveCanvus l屏幕画布屏幕画布-即屏幕窗口即屏幕窗口CClientDC的对象,例如的对象,例如dcCDC类的指针,例如类的指针,例如pDCWorkCanvusSaveCanvus214.3.1-4 位图的复制位图的复制 lCIm
16、age类对象之间的复制功能不可以用赋值来实现。因此,类对象之间的复制功能不可以用赋值来实现。因此,编写了编写了CopyImage()函数来实现两个函数来实现两个CImage对象间数据的复制对象间数据的复制l菜单菜单: “画布操作画布操作/工作画布复制到副本画布工作画布复制到副本画布” l源文件:第四章图象显示源文件:第四章图象显示.cppl函数:函数:CopyImage()22void CopyImage(CImage *pNewImg,CImage *pImage) RGBQUADColorTabs256;BYTE*pPixels, *pNewPixels; CDC*pDC,*pNewDC;
17、 nWidth=pImage-GetWidth();nHeight=pImage-GetHeight();nBitsPerPixel=pImage-GetBPP();nColorTableEntries=pImage-GetMaxColorTableEntries();if(!pNewImage-IsNull() pNewImage-Destroy();pNewImage-Create(nWidth,nHeight,nBitsPerPixel,0); if (nColorTableEntries0)pImage-GetColorTable(0,nColorTableEntries,ColorT
18、abs);pNewImage-SetColorTable(0,nColorTableEntries,ColorTabs); pDC= CDC:FromHandle(pImage-GetDC(); pNewDC = CDC:FromHandle(pNewImage-GetDC(); pNewDC-BitBlt(0,0,nWidth,nHeight,pDC,0,0,SRCCOPY); pImage-ReleaseDC(); pNewImage-ReleaseDC();23像素的整行复制像素的整行复制l为了能快速复制这些像素数据,可使用内存拷贝函数为了能快速复制这些像素数据,可使用内存拷贝函数mem
19、cpy来复制像素来复制像素void *memcpy( void *dest, const void *src, size_t count );destNew buffer srcBuffer to copy from countNumber of characters to copy例如:将第例如:将第y1行像素数据整行复制到行像素数据整行复制到y2行行nBytesPerLine=GetBytesPerLine(pImage);/整行像素数据字节数整行像素数据字节数 pPixel = (BYTE*) pImage-GetPixelAddress(0,y1);pNewPixel = (BYTE*
20、) pNewImage-GetPixelAddress(0,y2);memcpy(pNewPixel,pPixel,nBytesPerLine); pPixel 是是y1行像素数据的首地址行像素数据的首地址pNewPixel 是是y2行像素数据的首地址行像素数据的首地址244.4.4 改变调色板改变调色板灰阶调色板灰阶调色板蓝阶调色板蓝阶调色板默认调色板默认调色板25灰阶调色板灰阶调色板l调色板单元各分量的强度相等,色彩呈现灰色,分量值与单元序调色板单元各分量的强度相等,色彩呈现灰色,分量值与单元序号成正比号成正比 30000111122223333255255255255333调色板调色板内
21、存图象数据内存图象数据图象显示颜色图象显示颜色26设置设置灰阶灰阶调色板调色板l源文件:源文件:第四章图象显示第四章图象显示.cppl 函数:函数:OnSetGrayPalette()void CImageView:OnSetGrayPalette()RGBQUAD ColorTab;.for(int i=0;i256;i+)/设置灰阶调色板设置灰阶调色板ColorTab.rgbRed = i;ColorTab.rgbGreen = i; ColorTab.rgbBlue = i; SaveCanvus.SetColorTable(i, 1, &ColorTab);.27蓝阶调色板蓝阶调色板l
22、与灰阶调色板相似,它只保留蓝分量,而将红、绿分量全部设置与灰阶调色板相似,它只保留蓝分量,而将红、绿分量全部设置为为0 3RGB000010012002300325500255003调色板调色板内存图象数据内存图象数据图象显示颜色图象显示颜色28设置设置蓝阶蓝阶调色板调色板l源文件:源文件:第四章图象显示第四章图象显示.cppl函数:函数:OnSetBluePalette()void CImageView:OnGrayPalette()RGBQUAD ColorTab;.for(int i=0;i256;i+)/设置灰阶调色板设置灰阶调色板ColorTab.rgbRed = 0;ColorTa
23、b.rgbGreen = 0; ColorTab.rgbBlue = i; SaveCanvus.SetColorTable(i, 1, &ColorTab);.29默认调色板默认调色板(1)自定义了一个默认调色板,提供一组典型的颜色组合自定义了一个默认调色板,提供一组典型的颜色组合 30123255003调色板调色板内存图象数据内存图象数据图象显示颜色图象显示颜色序号序号颜色数颜色数内容内容0 78黑、蓝、绿、青、红、品红、褐色、淡灰黑、蓝、绿、青、红、品红、褐色、淡灰8 158深灰、亮蓝、亮绿、亮青、亮红、亮品红、黄、白深灰、亮蓝、亮绿、亮青、亮红、亮品红、黄、白16 3116灰阶,从黑到
24、白灰阶,从黑到白16个等级个等级32 10372高亮彩色高亮彩色 (高饱和、中饱和、低饱和各高饱和、中饱和、低饱和各24种色调种色调)104 17572中亮彩色中亮彩色 (高饱和、中饱和、低饱和各高饱和、中饱和、低饱和各24种色调种色调)176 24772低亮彩色低亮彩色 (高饱和、中饱和、低饱和各高饱和、中饱和、低饱和各24种色调种色调)248 2558黑色黑色30默认调色板默认调色板(2)序号序号颜色数颜色数内容内容0 78黑、蓝、绿、青、红、品红、褐色、淡灰黑、蓝、绿、青、红、品红、褐色、淡灰8 158深灰、亮蓝、亮绿、亮青、亮红、亮品红、黄、白深灰、亮蓝、亮绿、亮青、亮红、亮品红、黄、
25、白16 3116灰阶,从黑到白灰阶,从黑到白16个等级个等级32 10372高亮彩色高亮彩色 (高饱和、中饱和、低饱和各高饱和、中饱和、低饱和各24种色调种色调)104 17572中亮彩色中亮彩色 (高饱和、中饱和、低饱和各高饱和、中饱和、低饱和各24种色调种色调)176 24772低亮彩色低亮彩色 (高饱和、中饱和、低饱和各高饱和、中饱和、低饱和各24种色调种色调)248 2558黑色黑色RGBQUAD DefaultPalette256 = 0 x00,0 x00,0 x00,0 x00,0 xa8,0 x00,0 x00,0 x00,0 x00,0 xa8,0 x00,0 x00,0 x
26、a8,0 xa8,0 x00,0 x00,0 x00,0 x00,0 xa8,0 x00,0 xa8,0 x00,0 xa8,0 x00,0 x00,0 x54,0 xa8,0 x00,0 xa8,0 xa8,0 xa8,0 x00,0 x54,0 x54,0 x54,0 x00,0 xfc,0 x54,0 x54,0 x00,0 x54,0 xfc,0 x54,0 x00,0 xfc,0 xfc,0 x54,0 x00,0 x54,0 x54,0 xfc,0 x00,0 xfc,0 x54,0 xfc,0 x00,0 x54,0 xfc,0 xfc,0 x00,0 xfc,0 xfc,0 x
27、fc,0 x00,0 x00,0 x00,0 x00,0 x00,0 x14,0 x14,0 x14,0 x00,0 x20,0 x20,0 x20,0 x00,0 x2c,0 x2c,0 x2c,0 x00,0 x38,0 x38,0 x38,0 x00,31设置设置默认默认调色板调色板l源文件:源文件:第四章图象显示第四章图象显示.cppl函数:函数:OnSetDefaultPalette()RGBQUAD DefaultPalette256 = 。void CImageView:OnSetDefaultPalette().for(int i=0;i256;i+)/设置默认调色板设置默认调
28、色板 SaveCanvus.SetColorTable(i,1,&DefaultPalettei);32将副本画布调色板复制到工作画布将副本画布调色板复制到工作画布l源文件:源文件:第四章图象显示第四章图象显示.cppl函数函数:OnCopySavecanvusPaletteToWorkcanvus()void CImageView:OnCopySavecanvusPaletteToWorkcanvus()intnColorTableEntries; RGBQUAD ColorTabs256;nColorTableEntries=SaveCanvus.GetMaxColorTableEntries(); SaveCanvus.GetColorTable(0,nColorTableEntries,ColorTabs);WorkCanvus.SetColorTable(0,nColorTableEntries,ColorTabs);33 结束语结束语