已阅读5页,还剩29页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
20:37:53,冯筠:VC+图像编程,图像的读入和显示,西北大学信息学院 冯筠 2009年11月,20:37:53,冯筠:VC+图像编程,ViewDIB 打开文件的例子,学习分隔视图创建方法(多文档多视图结构) 学习串行化读取文件的机制 图像读取和显示的基本流程 在了解基本概念的基础上(API),了解图像类的设计方法 学习的MFC类: CFile CArchive 学习一些内存读取的API函数,20:37:53,冯筠:VC+图像编程,分隔窗的做法,在子窗口框架中定义分隔窗口对象 CSplitterWnd m_wndSplitter; 创建子窗口客户区时,定义分隔窗 BOOL CChildFrame:OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) / TODO: Add your specialized code here and/or call the base class m_wndSplitter.CreateStatic(this, 1, 2); m_wndSplitter.CreateView(0,0, RUNTIME_CLASS(CViewDIBView), CSize(800,200), pContext); m_wndSplitter.CreateView(0,1, RUNTIME_CLASS(CResultView), CSize(800,200), pContext); m_wndSplitter.SetRowInfo(0, 800, 1); m_wndSplitter.SetColumnInfo(0, 400, 1); m_wndSplitter.SetColumnInfo(1, 400, 1); return TRUE; /return CMDIChildWnd:OnCreateClient(lpcs, pContext); ,单文档,多视图结构,分辨率可以使用GetSystemMetrics(SM_CXSCREEN),20:37:53,冯筠:VC+图像编程,打开特定类型的文件,20:37:53,冯筠:VC+图像编程,串行化的概念,MFC的连续存储(serialize)机制俗称串行化 在你的程序中尽管有着各种各样的数据,serialize机制会象流水一样按顺序存储到单一的文件中,而又能按顺序地取出,变成各种不同的对象数据。 MFC 使用CArchive类管理不同的数据的存取,20:37:53,冯筠:VC+图像编程,CArchive 类概要,CArchive使用了缓冲区,即一段内存空间作为临时数据存储地,对CArchive的读写都先依次排列到此缓冲区,当缓冲区满或用户要求时,将此段整理后的数据读写到指定的存储媒质。 当建立CArchive对象时,应指定其模式是用于缓冲区读,还是用于缓冲区写。 可以这样理解,CArchive对象相当于铁路的货运练调度站,零散的货物被收集,当总量到达火车运量的时候,由火车装运走。 当接到火车的货物时,则货物由被分散到各自的货主。与货运不同的是,交货、取货是按时间循序执行的,而不是凭票据。因此必须保证送货的和取货的货主按同样的循序去存或取。 对于大型的货物,则是拆散成火车单位,运走,取货时,依次取各部分,组装成原物。,20:37:53,冯筠:VC+图像编程,CArchive 类概要,缓冲区指针 BYTE* m_lpBufStart,指向缓冲区,这个缓冲区有可能是底层CFile(如派生类CMemFile)对象提供的,但一般是CArchive自己建立的。 缓冲区尾部指针 BYTE* m_lpBufMax; 缓冲区当前位置指针 BYTE* m_lpBufCur; 初始化时,如果是读模式,当前位置在尾部,如果是写模式,当前位置在头部: 对于基本的数据类型,例如字节、双字等,可以直接使用“”、“”符号进行读出、写入。 用GetFile () 等函数可获得文件名等相关属性,用CArchive类进行读写的例子,20:37:53,冯筠:VC+图像编程,应用串行化打开文件的基本流程,对于一个文件而言,如果文件内数据的排列顺序是固定的,那么对于文件读和写从形式上只有使用的运算符的不同。 在MFC的框架/文档/视图结构中,一个文档的内部对象的构成往往是固定的,这种情况下,写到文件中时对象在文件中的布局也是固定的。 CDocument利用其基类CObject提供的Serilize虚函数,实现自动文档的读写。 当用户在界面上选择文件菜单/打开文件(ID_FILE_OPEN)时,CWinApp派生类的OnFileOpen函数被自动调用,它通过文档模板创建(MDI)/重用(SDI)框架、文档和视图对象,并最终调用CDocument:OnOpenDocument来读文件,CDocument:OnOpenDocument 自动调用Serialize 函数,20:37:53,冯筠:VC+图像编程,自定义串行化对象类,从CObject派生 该类实现了Serialize函数 该类在定义时使用了DECLARE_SERIAL宏 在类的实现文件中使用了IMPLEMENT_SERIAL宏 这个类有一个不带参数的构造函数,或者某一个带参数的构造函数所有的参数都提供了缺省参数,20:37:53,冯筠:VC+图像编程,CDib 类-图像类,20:37:53,冯筠:VC+图像编程,CDib的串行化函数,20:37:53,冯筠:VC+图像编程,CDib 真正的读取函数,20:37:53,冯筠:VC+图像编程,图像类的基本结构,先定义一系列图像处理API函数 C程序,包括读取,显示等等函数 DibAPI.h DibAPI.cpp 在API之上,设计CDib类 定义了图像数据相关的一些属性 将图像处理和打开的函数封装到类中 基本分类情况 打开图像(图像格式(讨论),读取方式) 显示图像,20:37:53,冯筠:VC+图像编程,图像文件的格式,主要介绍BMP图像文件格式,并且文件里的图像数据是未压缩的(2色,4色,16色,256色,24位真彩色) 因为图像的数字化处理主要是对图像中的各个像素进行相应的处理,而未压缩的BMP图像中的像素数值正好与实际要处理的数字图像相对应,这种格式的文件最合适我们对之进行数字化处理。 压缩过的图像是无法直接进行数字化处理的,如JPEG、GIF等格式的文件,此时首先要对图像文件解压缩,这就要涉及到一些比较复杂的压缩算法,本课程不涉及。,20:37:53,冯筠:VC+图像编程,BMP文件格式,文件头(BITMAPFILEHEADER) 主要包含文件的大小、文件类型、图像数据偏离文件头的长度等信息 位图信息头(BITMAPINFOHEADER) 包含图象的尺寸信息、图像用几个比特数值来表示一个像素、图像是否压缩、图像所用的颜色数等信息 颜色信息(RGBQUAD) 颜色信息包含图像所用到的颜色表,显示图像时需用到这个颜色表来生成调色板,但如果图像为真彩色,即图像的每个像素用24个比特来表示,文件中就没有这一块信息,也就不需要操作调色板 图形数据 表示图像的相应的像素值,图像的像素值在文件中的存放顺序为从左到右,从下到上,文件存储图像的每一行像素值时,如果存储该行像素值所占的字节数为4的倍数,则正常存储,否则,需要在后端补0,凑足4的倍数。,20:37:53,冯筠:VC+图像编程,图像格式:BMP文件头,BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。其结构定义如下: typedef struct tagBITMAPFILEHEADER WORD bfType; / 位图文件的类型,必须为“BM” DWORD bfSize; / 位图文件的大小,以字节为单位 WORD bfReserved1; / 位图文件保留字,必须为0 WORD bfReserved2; / 位图文件保留字,必须为0 DWORD bfOffBits; / 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位 BITMAPFILEHEADER;该结构占据14个字节。,20:37:53,冯筠:VC+图像编程,图像格式:位图信息头,BMP位图信息头数据用于说明位图的尺寸等信息。其结构如下: typedef struct tagBITMAPINFOHEADER DWORD biSize; / 本文件所占用字节数 LONG biWidth; / 位图的宽度,以像素为单位 LONG biHeight; / 位图的高度,以像素为单位 WORD biPlanes; / 目标设备的平面数,一般为1 WORD biBitCount/ 每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; / 位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; / 位图的大小,以字节为单位 LONG biXPelsPerMeter; / 位图水平分辨率,每米像素数 LONG biYPelsPerMeter; / 位图垂直分辨率,每米像素数 DWORD biClrUsed;/ 位图实际使用的颜色表中的颜色数 DWORD biClrImportant;/ 位图显示过程中重要的颜色数 BITMAPINFOHEADER;该结构占据40个字节。,20:37:53,冯筠:VC+图像编程,图像格式:颜色表,颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: typedef struct tagRGBQUAD BYTE rgbBlue;/ 蓝色的亮度(值范围为0-255) BYTE rgbGreen; / 绿色的亮度(值范围为0-255) BYTE rgbRed; / 红色的亮度(值范围为0-255) BYTE rgbReserved;/ 保留,必须为0 RGBQUAD;,20:37:53,冯筠:VC+图像编程,图像格式:位图信息,颜色表中RGBQUAD结构数据的个数由BITMAPINFOHEADER 中的biBitCount项来确定,当biBitCount=1,4,8时,分别有2,16,256个颜色表项,当biBitCount=24时,图像为真彩色,图像中每个像素的颜色用三个字节表示,分别对应R、G、B值,图像文件没有颜色表项。 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; / 位图信息头 RGBQUAD bmiColors1; / 颜色表头指针 BITMAPINFO; RGBQUAD结构中定义的颜色值中,红色、绿色和蓝色的排列顺序与一般真彩色图像文件的颜色数据排列顺序恰好相反,20:37:53,冯筠:VC+图像编程,图像格式:位图数据,位图数据记录了位图的每一个像素值或该对应像素的颜色表的索引值,图像记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。 位图的一个像素值所占的字节数:当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节,此时图像为真彩色图像。 当图像不是为真彩色时,图像文件中包含颜色表,位图的数据表示对应像素点在颜色表中相应的索引值,当为真彩色时,每一个像素用三个字节表示图像相应像素点彩色值,每个字节分别对应R、G、B分量的值,这时候图像文件中没有颜色表。,20:37:53,冯筠:VC+图像编程,图像格式:位图数据的计算,Windows规定图像文件中一个扫描行所占的字节数必须是4的倍数(即以字为单位),不足的以0填充,图像文件中一个扫描行所占的字节数计算方法: DataSizePerLine= (biWidth* biBitCount+31)/8;/ 一个扫描行所占的字节数 位图数据的大小按下式计算(不压缩情况下): DataSize= DataSizePerLine* biHeight。,20:37:53,冯筠:VC+图像编程,打开图像做的主要工作,将流数据读入相应的数据结构 BITMAPFILEHEADER, BITMAPINFOHEADER BITMAPINFO RGBQUAD 创建位图数据块(m_pDIB指向的数据块) 创建调色板 (m_pPalette指向的数据块) 创建CDC需要的位图(m_Bitmap),20:37:53,冯筠:VC+图像编程,存储图像的数据结构,在文档类中: CDib * m_pDib;/原始图像对象指针(右) CDib * m_pResultDib;/显示或处理效果图像对象指针 在CDib类中 CBitmap* m_pBitmap;/位图指针 CPalette* m_pPalette;/调色板指针 HBITMAP m_hBitmap;/位图块句柄 HDIB m_hDib; /设备无关位图句柄,20:37:53,冯筠:VC+图像编程,读取时用到的函数,hDIB=GlobalAlloc(GHND,dwSize) 分配内存,返回句柄 lpBI=(LPBYTE)GlobalLock(hDIB) 将该内存块全局锁定,返回指针 GlobalUnlock(hDib);解锁 强制类型转换 lpbi=(LPBITMAPINFOHEADER)lpBI CopyMemory(lpbi,lpDIB,dwSize) 内存复制,20:37:53,冯筠:VC+图像编程,读取中遇到的CFile函数,pFile-Read ( 将文件指针恢复到文件头,20:37:53,冯筠:VC+图像编程,跟踪打开(读入)图像文件的过程,ON_COMMAND(ID_FILE_OPEN, CWinApp:OnFileOpen) CViewDIBDoc:OnOpenDocument- CViewDIBDoc:Serialize- CDib:Serialize- CDib:Read(CFile *pFile)(*重点看,已注释) CDib:Create(LPBYTE lpDIB)-(*重点看,已注释) CDib:UpdateInternal-(*创建调色板,创建位图) CDib:BuildPalette()-(*已标注下节课详讲) DIBAPI-CreateDIBPalette- CDib:BuildBitmap() (*已标注下节课详讲) DIBAPI-DIBToDIBSection,20:37:53,冯筠:VC+图像编程,显示图像做的主要工作,将创建好的位图联系到设备上下文中 (pDC-SelectObject) 在OnDraw函数中绘制图像,20:37:53,冯筠:VC+图像编程,图形设备接口(GDI),GDI是Windows提供的一套函数和结构,以便于我们调用它们来绘图。 因为我们有不同的输出设备,各种显示器,各种打印机,他们有不同的打印驱动程序,GDI提供这样一个平台,屏蔽了他们的差异。 使用的GDI全部使用设备上下文(DC)作为显示设备的信息来源。因此,我们无需关心设备的特性。 在图形绘制当中,提供了一个叫做设备上下文(DC)的结构,是一个GDI提供的接口供我们来访问设备,所有的绘图都是通过设备上下文来进行。 因此,同一应用程序可以在配有不同的类型显示器的计算机上使用。应用程序不需要针对所有显示器进行更改,20:37:53,冯筠:VC+图像编程,设备描述表类(CDC),当 Windows 程序在屏幕、打印机或其他输出设备上画图时,它并不是将像素直接输出到设备上,而是将图绘制到由设备描述表(DC)表示的逻辑意义上的“显示平面”上去 . 设备描述表是一种数据结构,它包含 GDI 需要的所有关于显示平面情况的描述字段,包括相连的物理设备和各种各样的状态信息。 MFC 的 CDC 类将 Windows 设备描述表和获取设备描述表句柄的 GDI 函数就近封装在一起,而 CDC 派生类如 CPaintDC 和 CClientDC 则代表 Windows 应用程序使用的不同类型的设备描述表。,20:37:53,冯筠:VC+图像编程,CDC的用法,在 MFC 应用程序中获取设备描述表的一种方法是调用CWnd:GetDC,它返回指向表示 Windows 设备描述表的 CDC 对象的指针。在画图完毕时,要用 CWnd:ReleaseDC 释放由 CWnd:GetDC 获取的设备描述表指针 CPaintDC 用于在窗口客户区画图(仅限于 OnPaint 处理程序) CClientDC 用于在窗口客户区画图(除 OnPaint 外的任何处理程序) CWindowDC 用于在窗口内任意地方画图,包括非客户区 CMetaFileDC 用于向 GDI 元文件画图,20:37:53,冯筠:VC+图像编程,在CDC上绘画,CDC进行绘画的时候,可以使用多种资源,例如: pDC- SelectObject( CPen* pPen ); pDC- S
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年奶茶店室内设计服务合同协议
- 2026道德与法治五年级拓展空间 发展援助了解
- 2025工程(石材采购)合同
- 新苏教版三年级数学下册第五单元第2课《画垂线和点到直线的距离》教案
- 2026年中外教育史试题及答案
- 广电机房巡检制度
- 2026年医疗器具采购合同(1篇)
- 市政工程管道开挖钢便桥施工技术方案
- 闭经的益母草调理
- 扁桃体炎的免疫调节
- 2025年建信期货有限责任公司招聘笔试参考题库含答案解析
- 部编版三年级语文下册1-4单元同步练习题(带答案)测试
- 《直肠癌mri分期》课件
- 开滦集团荆个庄矿240万吨新井设计设计说明书
- 财务报表审计工作底稿编制案例
- 卵巢肿瘤教案
- 《肠造口并发症的分型与分级标准(2023版)》解读
- (完整版)内河船舶一类船员适任考试《避碰与信号》试题和答案
- 林木种质资源调查表(新表)
- 正畸治疗的生物机械原理-矫治力与牙齿的移动(口腔正畸学课件)
- 广电和通信设备调试工(高级)理论考试备考题库(重点500题)
评论
0/150
提交评论