• 2.61 MB
  • 2022-04-22 13:42:58 发布

基于动态协议的网络视频监控系统的设计与实现.doc

  • 136页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'基于动态协议的网络视频监控系统的设计与实现 长沙学院毕业设计摘要随着社会发展和科技进步,安防系统在社会生活和工业生产中发挥着越来越重要的作用,网络视频监控以其强大、丰富、便捷的特点成为当前安防系统的发展主流,在安防体系中占有举足轻重的地位。网络视频监控是完全基于IP技术,但由于我国目前的公网IP地址资源十分匮乏,对于网络视频监控系统中网络摄像头配置IP,最好的办法就是在廉价的动态IP上寻求解决途径。本课题的目的在于节约安防行业系统中的静态IP使用资源,设计并实现了基于动态协议的网络视频监控系统。在设计方面,首先对网络视频监控系统进行调研后,提出了本次系统设计的功能需求并探讨了基于动态网络视频监控系统的开发过程,着重分析了网络视频系统中前端摄像头驱动、视频流采集、Web平台以及TCPsocket功能实现的衔接并给出了详细的设计方案,最后对本次系统开发工作进行了全面总结和展望。关键词:网络视频监控系统,动态IP,视频流采集,TCPsocket-136- 长沙学院毕业设计ABSTRACTWiththedevelopmentofthesocietyandtheprogressofscienceandtechnology,securitysystemhasplayedanincreasinglyimportantroleinthesociallifeandindustrialproduction.Networkvideomonitoringsystemwithitspowerful,rich,andconvenientfeaturesbecomesthemaintrendofthedevelopmentofsecuritysystemandplaysanimportantroleinthesecuritysystem.NetworkvideomonitoringsystemiscompletelybasedonIPtechnology,butthestaticIPresourceisverylimitedinourcountryatpresent.AstotheconfigurationofIPcamerasinthenetworkvideomonitoringsystem,thebestwayistoseeksolutionsonthecheapdynamicIP.ThepurposeofthisdesignistosaveresourcesforstaticIPusedinthesecurityindustrysystem,anddesignandimplementavideomonitoringsystembasedondynamicprotocolofnetwork.Intermsofdesign,firstofall,afterinvestigationandresearchonnetworkvideomonitoringsystem,thispaperputsforwardthefunctionalrequirementsofsystemdesignanddiscussesthedevelopmentprocessonthebasisofdynamicnetworkvideomonitoringsystem.Thepaperplacesgreatemphasisonthethefrontcameradriver,videocollection,webplatformandtheTCPsocketfunctionofcohesion.Itgivesadetaileddesigningplanandfinallycarriesoutacomprehensivesummaryandoutlookforthesystemdevelopment.Keywords:NetworkVideoMonitoringSystem,TheDynamicIP,VideoCollection,TCPSockets-136- 长沙学院毕业设计-136- 长沙学院毕业设计前言随着宽带网络的普及,视频监控逐渐从本地监控向远程监控发展,网络视频监控系统应运而生。在网络视频监控系统中,由于监控业务平台和前端网络摄像机的通讯,需要前端网络摄像机一端处具有静态公网IP,这样才能让远程监控中心可以通过IP地址直接找到监控网络摄像机,然而我国目前静态IP资源非常短缺。本设计旨在实现基于动态协议的网络视频监控系统,系统需搭建监控业务平台、手机Wap客户端以及创建各个模块的接口。前端摄像头因条件限制则采用普通USB摄像头加驱动程序组建成的网络摄像头。在前端网络摄像头与业务平台对话之间,需拟定一条特殊协议,使前端网络摄像头能在动态IP环境支持下随时将自己数据发送给监控业务平台,使平台在节约IP资源的同时方便对前端摄像头的管理。整个系统搭建条件建立在本人实习工作期间所获取的专业技术与知识,经过学习加以吸收继而在原有的基础上创造设计并实现。本文档由两部分构成:设计说明书和过程管理资料。设计说明书部分中只包含本应用的设计说明书;过程管理资料包含毕业设计课题任务书、本科毕业设计开题报告、本科毕业设计中期报告、毕业设计指导教师评阅表、毕业设计评阅教师评阅表、毕业设计答辩评审表。-136- 长沙学院毕业设计-136- 长沙学院毕业设计需求规格说明书1引言1.1编写的目的本文档的目的主要是说明基于动态协议的网络视频监控系统的详细设计与实现。本文详细介绍了系统中各个模块的设计与实现细节以及关键技术的应用。其中,对每一个模块都配有相应的文字说明以及相关设计流程图给出。为使用户、相关分析人员对该系统的初始规定有更直观、全面的理解,文档中说明了本产品的各项功能需求、性能需求和数据要求并明确标识各功能的实现过程,阐述了实用背景、范围以及客户解决问题或达到目标所需的条件或权能,并提供了一个度量和遵循的基准。本文档读者:开发人员、测试人员、项目经理。1.2背景a.待开发的系统的名称:基于动态协议的网络视频监控系统的设计与实现;b.本项目的任务提出者:刘欣、开发者:杨刚、用户:适用于广大群众;c.本系统是“基于动态协议的网络视频监控系统”,是本人在广州网视通信息科技有限公司实习期间在学习与工作的基础上提升认知、经导师点拨提出设计的项目。本项目设计旨在节约网络视频监控系统中静态IP的使用,使监控前端摄像头与监控业务平台通过指定的动态协议进行对话。1.3定义CGI:公共网关接口CGI(CommonGatewayInterface)是WWW技术中最重要的技术之一,有着不可替代的重要地位。CGI是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程。CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体[7]。Socket:socket的英文原义是“孔”或“插座”。作为4BDSUNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机-136- 长沙学院毕业设计一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,象一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务[7]。J2ME:JavaME以往称作J2ME(JavaPlatform,MicroEdition),是为机顶盒、移动电话和PDA之类嵌入式消费电子设备提供的Java语言平台,包括虚拟机和一系列标准化的JavaAPI。它和JavaSE、JavaEE一起构成Java技术的三大版本,并且同样是通过JCP(JavaCommunityProcess)制订的。MySql:小型关系型数据库管理系统,具有体积小、速度快、总体拥有成本低、开放源码等特点,支持多种操作系统,为多种编程语言提供API,操作简单。HTTP:(hypertexttransportprotocol,超文本传送协议)一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。JSP:JSP(JavaServerPages)是由SunMicrosystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件(*.jsp)。用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。1.4参考资料[1]潘国辉.智能网络视频监控[M].北京:清华大学出版社,2010:11-28.[2]郑亮亮,吴小强.IP高清监控系统的工程设计实践[J].安防经理第31期:3-9.[3]罗宏亮.IP视频监控系统的稳定性设计[D].安防经理第32期:2-11.[4]杨延双,张建,王全民.TCPIP协议分析与应用[C].机械工业出版社.2010.[5]王挺等.C++程序设计[M].北京:清华大学出版社.2005.[6]百度百科.http://baike.baidu.com/.2任务概述2.1目标-136- 长沙学院毕业设计本项目旨在设计基于动态协议的网络视频监控系统,包含前端网络摄像头的模拟、Web业务平台、手机WAP客户端以及各个模块之间对话的铺设。在网络视频监控系统中,由于监控业务平台和前端网络摄像机的通讯,需要网络摄像机具有静态的公网IP,这样才能让监控业务平台可以通过IP地址寻找到网络摄像机。实现本系统功能关键设计在于监控业务平台与网络摄像机对话之间添加一条协议:网络摄像机在上线获取监控平台信息时,将自身信息及动态IP信息发送给监控业务平台,使监控业务平台能有效对摄像头进行管理。整个系统拓扑结构图如图2.1所示。图2.1系统拓扑结构图2.2用户的特点最终用户:适用于广大群众操作人员:适用于广大群众2.3假定和约束1)国家相关草案规定,“公共安全视频图像信息系统管理不得泄露国家秘密和商业秘密,不得侵犯个人隐私及其他合法权益”,本系统的设计与安全监控的摄像头存在本质区别:l拍摄用途:据用户需求进行某个人区域监控l安装位置:视用户需求安装在某合法领域l拍摄区域:视用户需求监控在某合法领域l画面大小:为适应手机观看,画面大小与帧数做必要精简l画面清晰度:USB摄像头模拟成网络摄像头,清晰度较低-136- 长沙学院毕业设计1)开发环境约束:如表2.1所示。表2.1开发环境约束表需求名称详细要求数据库服务器一台服务器作为数据库服务器,要求:CPUP41G以上,内12G以上,硬盘80G以上;操作系统Windows8;数据库系统为mysql应用服务器一台服务器作为应用服务器,要求:CPUP41G以上,内存1G以上,硬盘80G以上;操作系统Windows8;应用服务器系统为Web前端摄像头通过对USB摄像头的模拟,让其实现网络摄像头的功能客户端1、IE浏览器,要求在InternetExplorer6.0或更高版本浏览器中运行。2、手机Wap客户端3需求规定3.1对功能的规定系统在模块上划分为为三大部分:Web业务平台、前端网络摄像头、手机Wap客户端。整个系统的时序图如图3.1所示。-136- 长沙学院毕业设计图3.1系统时序图3.1.1Web业务平台系统功能规定系统提供强大的平台管理业务支撑能力,主要包括权限管理,用户管理,设备管理,系统管理等功能,如图3.2所示。-136- 长沙学院毕业设计图3.2Web业务平台系统用例图l权限管理角色管理:设置和更新不同权限的系统管理角色信息模块管理:设置和更新系统模块和非系统模块系统用户管理:可对系统管理员进行设置,包括启用和禁用相关信息l用户管理用户信息列表:查询,增加,更新用户相关信息用户设备信息:查询,增加,更新系统设备相关信息,如摄像机IP,端口,设备类型,名称等l设备管理设备信息管理:管理和查询系统内所有设备信息设备参数管理:对设备协议,地址,波特率等相关参数进行配置l系统管理日志管理:查看平台管理系统用户登录信息用户登录信息管理:查看前台系统用户登录信息-136- 长沙学院毕业设计手机登录信息管理:查看用户手机登录相关信息3.1.2前台门户功能规定基于运营商角色的Web配置管理功能。包含个人资料,所有设备,设备管理,用户管理等。用例图如图3.3所示。图3.3用户用例图l个人资料管理查看个人资料绑定邮箱和手机,密码丢失后方便找回自行修改用户部分信息以及密码l查看所有设备查看系统所有设备,支持搜索查看和分组查看l设备管理添加设备:方便快捷的将新安装的设备加入系统系统3.1.3手机Wap客户端功能规定l实时监控:用户登录后可对自己名下的摄像头所监控区域进行随时随地的实时监控-136- 长沙学院毕业设计3.1.4前端摄像头功能规定l捕获视频源l采集监控视频以及画面3.2对性能的规定3.2.1精度时间精度:时间的保存精确到秒。3.2.2时间特性要求平均响应时间:在网速大于100KB每秒的条件下,在5秒之内能打开并显示页面。常用功能响应时间:使用频率高的功能需要优化好,比如主页的显示,在10秒内能获取到数据库返回的数据并显示在页面上。3.2.3灵活性默认支持的用户数需要达到上万级别的规模。当用户数超过万级别,仅仅通过增加成本低廉的硬件,进行简单地配置,可以支持更多的用户,而不需要对程序进行大的改动。增加新的功能是容易扩展的,很少需要动底层代码,只需要加上层的文件。3.3输入输出要求本系统中存在不同的功能模块,对模块之间的输入输出项作特定的规范和要求,可以使得定义的输入输出项更加合理有效,方便不同模块间数据的传递。系统中用户具体的输入输出要求如表3.1所示。表3.1输入输出要求表功能编号功能名称输入系统响应输出TK-USER-01用户注册信息的长度验证用户名、密码、注册邮箱验证注册邮箱、用户名、密码长度是否符合要求输出长度验证结果信息TK-USER-02用户注册信息的格式验证注册邮箱验证注册邮箱是否符合特定的邮箱格式输出格式验证结果信息-136- 长沙学院毕业设计TK-USER-03用户注册信息的一致性验证密码、确认密码验证密码和确认密码输入是否一致输出一致性验证结果信息TK-USER-04用户注册信息的异步验证注册邮箱、用户名查询用户表是否存在用户输入的数据,并将查询结果返回到页面中输出验证结果信息TK-USER-05空值验证邮箱,密码判断邮箱输入框、密码输入框是否为空输出验证信息系统中用户具体的输入输出要求如表3.2所示。表3.2输入输出要求表功能编号功能名称输入系统响应输出TK-CAMERA-01添加摄像头信息的长度验证摄像头名、密码、IP验证摄像头名、密码、IP长度是否符合要求输出长度验证结果信息TK-USER-02摄像头信息的格式验证IP验证IP信息是否符合特定的IP格式输出格式验证结果信息3.4数据管理能力要求视频存储估算:视存储格式、视频码流而定3.5故障处理要求根据系统的需求说明书,项目负责人、软件分析设计人员以及编程人员对系统进行检查,维护和整修。3.6其他专门要求采用良好的人/机交互界面设计以及目前主流的浏览器技术,以提高系统对用户操作和控制的支持。系统提供方便学习的人机界面,提供直观、快捷的窗口操作。4运行环境规定4.1设备-136- 长沙学院毕业设计智能终端设备4.2支持软件支持软件见表4.1。表4.1支持软件一栏表名称技术参数性能备注操作系统Windows8Web服务器MyEclipse8.5/Tomcat6.0非并发后期可考虑tomcat集群或增加前置代理机制数据库服务器MySQL5.5并发200个数据连接,连接池机制。应用服务器Tomcat6.0/MySQL5.5非并发10,并发100个数据连接,连接池机制。后期可考虑tomcat集群或增加前置代理机制4.3接口1.外部接口:① 网页用户界面:在用户界面部分,根据需求分析的结果,用户需要一个用户友善界面。在界面设计上,应做到简单明了,易于操作,并且要注意到界面的布局。外观上也要做到合理化,考虑到用户多对WINDOW风格较熟悉,应尽量向这一方向靠拢。在设计语言上,已决定使用HTML语言进行编程,在界面上可使用所提供的可视化组件向WINDOWS风格靠近。总的来说,系统的用户界面应作到可靠性、简单性、易学习和使用。② 软件接口:服务器程序使用C++语言进行编程,完成对功能的实现以及接口的访问。在网络软件接口方面,使用一种socket的传输协议,对数据进行网络传输及接收。2.硬件接口:① 在输入方面,对于摄像头,SD卡的输入,可用C++程序的标准输入/输出,对输入进行读写在输出方面,用C++程序的标准输入/输出,对其进行处理。网络输出方面,我们通过cgi接口协议,以及socket进行实现。-136- 长沙学院毕业设计基于动态协议的网络视频监控系统软件设计说明书V1.3编制审核批准长沙学院二零一三年四月十日-136- 长沙学院毕业设计软件设计说明书1引言1.1编写目的本文档是基于动态协议的网络视频监控系统的软件设计说明书。通过此文档有助于开发人员与设计人员对功能与模块的整体把握,便于用户对网络视频监控系统的深入了解。文档中阐述了系统模块开发的背景、术语、软件结构和功能等一系列相关内容,旨在帮助读者了解这一系统模块的软件结构和包含的功能,方便后续整理和测试工作的开展,为项目的最终验收打下一个很好的基础。本文档的预期读者:项目开发人员、测试人员。1.2背景a.待开发软件系统的名称:基于动态协议的网络视频监控系统的设计与实现;b.列出本项目的任务提出者:刘欣、开发者:杨刚、用户:适用于广大群众。1.3定义CGI:公共网关接口CGI(CommonGatewayInterface)是WWW技术中最重要的技术之一,有着不可替代的重要地位。CGI是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程。CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体[7]。Socket:socket的英文原义是“孔”或“插座”。作为4BDSUNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,象一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务[7]。J2ME:JavaME以往称作J2ME(JavaPlatform,Micro-136- 长沙学院毕业设计Edition),是为机顶盒、移动电话和PDA之类嵌入式消费电子设备提供的Java语言平台,包括虚拟机和一系列标准化的JavaAPI。它和JavaSE、JavaEE一起构成Java技术的三大版本,并且同样是通过JCP(JavaCommunityProcess)制订的。WTK:WTK的全称是SunJ2MEWirelessToolkit——Sun的无线开发工具包。这一工具包的设计目的是为了帮助开发人员简化j2me的开发过程。使用其中的工具可以开发与JavaTechnologyfortheWirelessIndustry(JTWI,JSR185)规范兼容的设备上运行的j2me应用程序。1.4参考资料[1]潘国辉.智能网络视频监控[M].北京:清华大学出版社,2010:11-28.[2]郑亮亮,吴小强.IP高清监控系统的工程设计实践[J].安防经理第31期:3-9.[3]罗宏亮.IP视频监控系统的稳定性设计[D].安防经理第32期:2-11.[4]杨延双,张建,王全民.TCPIP协议分析与应用[C].机械工业出版社.2010.[5]王挺等.C++程序设计[M].北京:清华大学出版社.2005.[6]百度百科.http://baike.baidu.com/.2总体设计2.1需求规定参看需求规格说明书。2.2运行环境a.操作系统windowsXP/Vista/Win7/Win8b.中间件Myeclipse、MicrosoftVisualC++、Tomcat6.0c.数据库MySql5.52.3基本设计概念和处理流程本系统的设计共分为三大模块,分别为Web业务平台、前端摄像头、手机Wap客户端。其中Web业务平台是基于MVC模式,采用SSH框架、运用JQuery技术构建而成。前端摄像头则采用USB电脑摄像头通过驱动程序使其模拟成网络摄像头,具有收集画面以及视频的功能。手机Wap客户端则能够在一定条件下对网络摄像头监控画面进行查看。整个系统中,每个模块的功能都是紧密相连的,系统的事件处理流程如图2.1所示:-136- 长沙学院毕业设计图2.1系统事件处理流程图2.4系统结构系统结构如图2.2所示。-136- 长沙学院毕业设计图2.2系统结构图-136- 长沙学院毕业设计2.5功能需求与程序的关系本条用一张矩阵图说明各项功能需求的实现同各模块的分配关系。如表2.1所示。表2.1功能需求与程序模块的关系视频模块用户管理模块摄像头管理模块系统模块实时视频√用户管理√摄像头管理√系统设置√3接口设计3.1用户接口Web登录界面。3.2外部接口网页用户界面:在用户界面部分,根据需求分析的结果,用户需要一个用户友善界面。在界面设计上,应做到简单明了,易于操作,并且要注意到界面的布局。外观上也要做到合理化,考虑到用户多对WINDOW风格较熟悉,应尽量向这一方向靠拢。在设计语言上,已决定使用HTML语言进行编程,在界面上可使用所提供的可视化组件向WINDOWS风格靠近。总的来说,系统的用户界面应作到可靠性、简单性、易学习和使用。在输入方面,对于摄像头,SD卡的输入,可用C++程序的标准输入/输出,对输入进行读写。3.3内部接口服务器程序使用C++语言进行编程,完成对功能的实现以及接口的访问。在网络软件接口方面,使用TCPsocket的服务功能,对数据进行网络传输及接收。4运行设计4.1运行模块组合-136- 长沙学院毕业设计前端网络摄像头利用USB摄像头通过程序驱动而成。5系统数据结构设计参看数据库设计说明书。6系统出错处理设计6.1出错信息由于Web业务平台中很多地方都涉及到数据的验证,所以特别将有可能出现的错误以一览表的形式展现出来,如表6.1所示。表6.1出错信息一览表出错情况输出信息提示含义处理方法不能注册该帐号已经被注册每个帐号只能注册一次直接登录请输入其他帐号帐号为主键输入正确帐号用户名长度应在1-18位之间用户名为空或过长输入1-18位的帐号密码长度应在6-18位之间密码长度过短或过长输入6-18位的密码请确认密码尚未确认密码确认密码密码不一致确认密码框和密码框输入不一致重新输入确认密码帐号不能为空尚未输入帐号输入帐号登录失败密码不能为空尚未输入密码输入密码帐号或密码不对帐号和密码不匹配重新输入邮箱格式不对邮箱输入有误输入正确的邮箱摄像头信息添加失败摄像头ID添加失误摄像头ID为12位数字输入12位的数字IP输入错误IP格式错误确认IP格式6.2补救措施-136- 长沙学院毕业设计1)后备技术周期性地把磁盘信息记录到光盘上去,当原始系统数据万一丢失时,就启用该副本,作为对于磁盘媒体的一种后备技术。2)降效技术信息发布系统的降效技术可以采用手工操作和数据的人工记录。7Web业务平台设计说明7.1模块描述此模块为平台提供了强大的业务支撑能力,主要试用系统管理者进行对Web业务平台的管理,包括权限管理,用户管理,设备管理,系统管理等功能。其页面设计图7.1所示。图7.1模块页面设计图7.2功能l权限管理角色管理:设置和更新不同权限的系统管理角色信息模块管理:设置和更新系统模块和非系统模块系统用户管理:可对系统管理员进行设置,包括启用和禁用相关信息l用户管理用户信息列表:查询,增加,更新用户相关信息用户设备信息:查询,增加,更新系统设备相关信息,如摄像机IP,端口,设备类型,名称等l设备管理设备信息管理:管理和查询系统内所有设备信息-136- 长沙学院毕业设计设备参数管理:对设备协议,地址,波特率等相关参数进行配置l系统管理日志管理:查看平台管理系统用户登录信息用户登录信息管理:查看前台系统用户登录信息手机登录信息管理:查看用户手机登录相关信息7.3输入项异步验证输入项的名称、标识、数据类型、格式、范围、输入方式如表7.1所示。表7.1异步验证输入项名称标识数据类型格式范围输入方式用户iduser_idvarchar字符串长度在0~20之间手动输入用户名user_namevarchar字符串长度在1~20之间手动输入平台登录端验证输入项的名称、标识、数据类型、格式、范围、输入方式如表7.2所示。表7.2平台登录验证输入项名称标识数据类型格式范围输入方式用户iduser_idvarchar字符串长度在0~20之间手动输入用户名user_namevarchar字符串长度在1~20之间手动输入密码passwordvarchar字符串长度在6~18之间手动输入7.4输出项注册模块功能的输出内容皆为提示信息。7.5流程逻辑Web业务平台系统流程示意图如图7.2所示。-136- 长沙学院毕业设计表7.2Web业务平台系统流程示意图8前台门户设计说明8.1模块描述-136- 长沙学院毕业设计基于运营商角色的WEB配置管理功能。此模块适用于用户,包含个人资料,所有设备,设备管理。8.2功能l个人资料管理可绑定邮箱和手机,密码丢失后方便找回可自行修改用户部分信息以及密码用户资料管理l所有设备可查看系统所有设备,支持搜索查看和分组查看l设备管理添加设备:方便快捷的将新安装的设备加入系统系统8.3输入项异步验证输入项的名称、标识、数据类型、格式、范围、输入方式如表8.1所示。表8.1异步验证输入项名称标识数据类型格式范围输入方式用户iduser_idvarchar字符串长度在0~20之间手动输入用户名user_namevarchar字符串长度在1~20之间手动输入平台登录端验证输入项的名称、标识、数据类型、格式、范围、输入方式如表8.2所示。表8.2平台登录验证输入项名称标识数据类型格式范围输入方式用户iduser_idvarchar字符串长度在0~20之间手动输入用户名user_namevarchar字符串长度在1~20之间手动输入密码passwordvarchar字符串长度在6~18之间手动输入8.4输出项注册模块功能的输出内容皆为提示信息。9网络摄像头设计说明9.1模块描述-136- 长沙学院毕业设计此模块为USB摄像头通过程序驱动成为网络摄像头,功能上使其能采集监控画面并进行上传到平台。9.2功能l实时监控对所监控区域进行随时随地的实时监控9.3接口以下为驱动程序之间的接口:文件名:IocpModeSvr.h类名:CIocpModeSvr类说明:本类是一个完成端口模型的网络服务器引擎运行平台:WinNT3.5以上版本、Windows2000输入接口说明:本类接收一个回调函数地址,该函数具有如下原型void_stdcallProcessRecvData(unsignedlongsIP,SOCKETsClient,char*pData,unsignedlongDataLength);此回调函数用来接收从客户端发来的数据或者某客户端断开连接的通知(有始有终)unsignedlongsIP:表示数据通知的客户端IP地址SOCKETsClient:服务器用于和客户端通迅的套接字,如果不是断开连接消息,则您可使用此参数调用SendMsg向客户端发送数据char*pData:本次操作的数据unsignedlongDataLength:本次操作数据的数据长度提示:如果pData==NULL并且DataLength则表示那是客户端断开连接的消息.输出接口说明:引擎初始化函数,第一参为回调地址(必须正确填写),第二参为服务端口号初始化成功返回真,否则返回假boolInit(ProcessRecvData*pProcessRecvData,unsignedlong-136- 长沙学院毕业设计iSvrPort=SVRPORT);引擎反初始化函数,请在程序退出时调用,或者在程序需要重新启动服务时调用voidUnInit();以下在关于发送消息函数组的接口说明1、向目标IP客户端发送数据,第一参为目标客户端IP,第二参为数据区地址,第三参为数据区长度成功"提交"返回真,否则返回假,那可能是因为客户端已经断开或者根本就没有连接。boolSendMsg(LPCTSTRTargetIp,char*pData,unsignedlongLength);2、向目标套接字发送数据第一参为客户端套接字第二参为数据区地址第三参为数据区长度成功"提交"返回真,否则返回假那可能是因为客户端已经断开连接提示:此函数为不需要检索的发送数据函数,具有高效率的特性。你可以在你的数据通知回调中以第二参的sClient直接填写于第一参中发送数据,如果你在接收到数据时需要回传消息,请使用此函数成功"提交"返回真,否则返回假boolSendMsg(SOCKETsClient,char*pData,unsignedlongLength);3、向所有连线客户端发送数据发送数据到所有已经正确连线的客户端第一参为数据区地址第二参为数据区长度成功"提交"返回真,否则返回假大部分情况下都会返回真^_^boolSendMsgToAll(char*pData,unsignedlongLength);4、向除了某个IP外的其它所有在线客户端发送数据-136- 长沙学院毕业设计第一参为除外的IP第二参为数据区地址,第三参为数据区长度,成功"提交"返回真,否则返回假大部分情况下都会返回真boolSendMsgToOther(LPCTSTRSourceIp,char*pData,unsignedlongLength);5、向除了某个Socket久的其它所有在线客户端发送数据第一参为除外的Socket第二参为数据区地址第三参为数据区长度成功"提交"返回真,否则返回假大部分情况下都会返回真boolSendMsgToOther(SOCKETExceptSocket,char*pData,unsignedlongLength);附助函数组11、constchar*GetLocalIpAdd()返回本地Ip地址,返回值为点分十进制的字符串2、unsignedshortGetSvrPort()返回服务使用的侦听端口号附助函数助21、boolDisConnectClient(LPCTSTRClientIp);切断参数中指定的IP的客户端的连接,成功返回真,否则返回假。2、boolDisConnectClient(SOCKETsClient);切断参数中指定的客户机的连接,参数中指定了要切断了套接口。3、voidDisConnectAll();切断所有客户机的连接。10手机Web客户端设计说明10.1模块描述此模块主要为用户用手机观看监控画面而设计,可通过智能手机浏览器直接输入摄像头IP即可观看监控画面。-136- 长沙学院毕业设计10.2功能l画面监控对前端摄像头监控的画面进行监控。-136- 长沙学院毕业设计基于动态协议的网络视频监控系统数据库设计说明书V1.3编制审核批准长沙学院二零一三年四月十六日-136- 长沙学院毕业设计数据库设计说明书1.引言1.1编写目的本说明书说明“基于动态协议的网络视频监控系统”的数据库设计与结构情况,用于开发人员进行项目设计,同时也为后续的工作提供了良好的使用说明,也可以作为未来版本升级时的重要参考资料说明。预期读者:数据库管理者1.2背景a.待开发数据库的名称:NETWORK_VIDEO.dbb.使用此数据库的软件系统的名称:基于动态协议的网络视频监控系统c.列出本项目的任务提出者:刘欣、开发者:杨刚、用户:数据库管理员。1.3定义MySql:小型关系型数据库管理系统,具有体积小、速度快、总体拥有成本低、开放源码等特点,支持多种操作系统,为多种编程语言提供API,操作简单。实体表:用户实际使用的客观表格1.4参考资料本项目的《需求规格说明书》; 本项目相关的其他参考资料。2数据库环境说明数据库名称:NETWORK_VIDEO.db数据库系统:MySQL数据库宿主环境:windows8编程工具:MyEclipse8.5-136- 长沙学院毕业设计3数据库的命名规则本数据库采用26个区分大小写的英文字母和0~9这十个自然数以及下划线‘_’组成,共63个字符。不能出现其他字符,注释除外。其遵循以下命名规则:(1)所有的命名都不得超过30个字符的系统限制,变量名在不包含标识符‘@’的情况下不超过29个字符。(2)保证所有命名中不包含保留词、数据库应用系统或者常用访问冲突的词语。(3)所有的命名需遵循首字母小写,若该命名为多词组合,应第二个词语及以后的词语首字母大写,其余字母小写。(4)连接表命名以连接表名之间加下划线命名。4逻辑结构设计4.1概念模型结构设计概念模型结构设计如图4.1所示。图4.1概念模型结构图5物理结构设计5.1表结构设计1)用户信息如表5.1所示。表5.1用户信息表序号字段名类型长度主键是否为空描述1use_idvarchar10是否用户ID2user_namevarchar10否否用户名3passwordvarchar10否否密码4sexvarchar2否否性别-136- 长沙学院毕业设计5e_mailvarchar80否是邮箱地址6phonevarchar20否是电话1)摄像头信息如表5.2所示。表5.2摄像头信息表序号字段名类型长度主键是否为空描述1camera_idvarchar10是否摄像头ID2camera_namevarchar10否否摄像头名称3camera_ipvarchar10否否摄像头IP4typevarchar10否否摄像头类型5addressvarchar80否否摄像头安装地址2)安装工单如表5.3所示。表5.3安装工单表序号字段名类型长度主键是否允许为空描述1order_iditerger10是否工单ID2user_idvarchar10否否用户ID3camera_idvarchar10否否摄像头ID4datevarchar80否否启用日期5.2物理结构设计物理结构图设计如图5.1所示。图5.1物理结构设计图6安全性设计为提高平台的安全性,不同的角色具有不同的权限,如图表6.1所示。表6.1角色与权限角色可以访问的表操作权限-136- 长沙学院毕业设计普通用户User查询、更新Camera查询、更新、添加Order查询、更新、添加平台管理用户User查询、更新、添加、删除Camera查询、更新、添加、删除Order查询、更新、添加、删除另外用户只能用帐号登录到平台中,通过这一平台访问数据库,而没有其他途径操作数据库。具体设计如表6.2、表6.3和表6.4所示。表6.2用户表表名User主键user_id其他排序字段无索引字段e_mail序号字段名称数据类型(精度范围)允许为空Y/N唯一Y/N区别度默认值约束条件/说明1user_idvarchar(10)NY高无PK用户id2user_namevarchar(10)NN低无用户名字3passwordvarchar(10)NN低无用户密码4sexvarchar(2)NN低男、女用户性别5e_mailvarchar(80)NN低无用户邮箱6phonevarchar(20)NN低无用户电话sql脚本createtableUser(user_idintnotnullauto_increment,user_namevarchar(10)notnull,passwordvarchar(10)notnull,sexvarchar(2)notnull,e_mailvarchar(80)notnull,primarykey(user_id));备注无表6.3摄像头表表名Camera主键camera_id-136- 长沙学院毕业设计其他排序字段无索引字段camera_name序号字段名称数据类型(精度范围)允许为空Y/N唯一Y/N区别度默认值约束条件/说明1camera_idvarchar(10)NY高无PK摄像头ID2camera_namevarchar(10)NN低无摄像头名字3camera_ipvarchar(10)NN低无摄像头IP4typevarchar(10)NN低无摄像头类型5addressvarchar(80)NN低无摄像头安装地址sql脚本createtableCamera(camera_idvarchar(10)notnullauto_increment,camera_namevarchar(10)notnull,camera_ipvarchar(10)notnull,typevarchar(10)notnull,addressvarchar(80)notnull,primarykey(camera_id));备注无表6.4工单表表名Order主键order_id其他排序字段无索引字段无序号字段名称数据类型(精度范围)允许为空Y/N唯一Y/N区别度默认值约束条件/说明1order_idintNY高无PK工单帐号2user_idvarchar(10)NY高无PK、FK用户ID3camera_idvarchar(10)NN低无PK、FK摄像头ID4datevarchar(80)NN低无创建时间-136- 长沙学院毕业设计sql脚本createtableorder(order_idintnotnull,user_idvarchar(10)notnull,camera_idvarchar(10)notnull,datevarchar(80)notnull,primarykey(order_id));备注无7优化本系统的数据库遵循“简单实用”的设计原则,设计尽可能简洁的数据库表和连接去实现协同办公平台用户入组模块的功能。每个数据库表字段不多,但都是需求必不可少的。对于数据库表与表之间的访问,则是用两个表的主键构成中间表,解决多表之间的连接问题。8数据库管理与维护说明数据库给予数据库管理员专门管理,并定期负责备份,防止数据丢失。-136- 长沙学院毕业设计基于动态协议的网络视频监控系统测试用例说明书V1.3编制审核批准长沙学院二零一三年四月二十六日-136- 长沙学院毕业设计测试用例说明书1引言1.1编写的目的本文档为“基于动态协议的网络视频监控系统”测试活动提供范围、方法、资源和进度方面的指导。预期的读者范围包括:开发人员、测试人员、用户。1.2背景a.待开发的系统的名称:基于动态协议的网络视频监控系统;b.本项目的任务提出者:刘欣、开发者:杨刚、用户:适用于广大群众;c.本系统主要是基于动态协议的网络视频监控系统设计与实现。是本人在广州网视通信息科技有限公司实习期间在学习与工作的基础上提升认知、经导师点拨提出的。本项目设计旨在节约网络视频监控系统中静态IP的使用,使监控前端摄像头与监控业务平台通过指定的协议进行动态对话。1.3定义MySql:小型关系型数据库管理系统,具有体积小、速度快、总体拥有成本低、开放源码等特点,支持多种操作系统,为多种编程语言提供API,操作简单。Socket:socket的英文原义是“孔”或“插座”。作为4BDSUNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,象一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。1.4参考资料参考资料如表1.1所示。-136- 长沙学院毕业设计表1.1参考资料表序号标题文件名称资料来源1软件设计说明书软件设计说明书.doc本人单独设计2需求规格说明书需求规格说明书.doc本人单独设计2测试用例测试环境见表2.1所示表2.1测试环境项目名称基于动态协议的网络视频监控系统设计与实现程序版本V1.0测试环境硬件:内存:2G,硬盘:500G,处理器:Intel(R)Core(TM)i3CPU软件:操作系统:Win8、浏览器:360浏览器,数据库:NavicatforMySQL2.1注册功能测试详细说明注册功能测试详细说明见表2.2所示。表2.2注册功能测试详细说明表测试目的基于动态协议的网络视频监控系统注册功能模块是否达到预期要求,满足需求规定功能特性业务平台注册功能是否完善预置条件测试环境已搭建、软件可测试参考信息基于动态协议的网络视频监控系统需求规格说明书、软件设计说明书特殊规程无设计人杨刚设计时间2013-3-1测试记录人杨刚测试时间2013-5-25功能模块名称用例编号操作步骤/测试数据预期结果实际结果判定功能性(业务平台注册验证)注册业务平台验证TK-REG-011.打开用户注册页面2.在用户名输入正确ID提示输入正确同预期通过-136- 长沙学院毕业设计TK-REG-021.打开用户注册页面2.在用户名输入已输入ID此ID已被注册同预期通过TK-REG-031.打开用户注册页面2.在用户名处,输入为空提示用户名不能为空同预期通过TK-REG-041.打开用户注册页面2.在密码处,输入密码提示输入正确同预期通过TK-REG-051.打开用户注册页面2.在确认密码处,输入和密码不一致的字符提示密码不一致同预期通过TK-REG-061.打开用户注册页面2.密码输入处为空提示请输入密码同预期通过TK-REG-071.打开用户注册页面2.在注册邮箱处,输入格式正确的邮箱(尚未注册)提示输入正确同预期通过TK-REG-081.打开用户注册页面2.在注册邮箱处,输入错误格式提示邮箱格式输入错误同预期通过2.2登录功能模块详细说明登录功能模块详细说明见表2.3所示。表2.3登录功能模块详细说明表测试目的验证基于动态协议的网络视频剪卡系统登录功能模块是否达到预期要求,满足需求规定功能特性登录预置条件测试环境已搭建、软件可测试参考信息基于动态协议的网络视频监控系统的需求规格说明书、软件设计说明书特殊规程无设计人杨刚设计时间2013-3-1测试记录人杨刚测试时间2013-5-25功能模块名称用例编号操作步骤/测试数据预期结果实际结果判定功能性(登录)登录登录TK-LOG-011.打开用户登录页面2.输入正确格式的帐号密码3.点击“登录”跳入到下一界面同预期通过-136- 长沙学院毕业设计TK-LOG-021.打开用户登录页面2.输入错误格式的帐号密码3.点击“登录”跳入到帐号或密码错误界面同预期通过TK-LOG-031.打开用户登录界面2.输入帐号,将密码置空3.点击“登录”提示密码不能为空同预期通过TK-LOG-041.打开用户登录界面2.将帐号密码置空3.点击“登录”提示帐号不能为空同预期通过-136- 长沙学院毕业设计结论2012年12月,我开始着手毕业设计的准备工作,一开始对于毕业设计感到茫然、踟躇,经过大量资料的翻阅以及工作上的感悟有了较为清晰的脉络,到现在毕业设计已经大致完善。期间的经历无法用言语来表达。毕业设计经历了前期相关大量文献资料的查阅和中期的研究开发以及后期的调试完善工作,基于动态协议的网络视频监控系统设计已基本达到要求并实现预期功能。很欣慰通过自己的这几个月的劳动能够有如此大的收获,但是更多的是对于毕业设计的感悟和体会。感悟的是自己能够完成这一次设计辛勤耕耘而洒下的汗水有所值得,体会的是面对之初自己一直以为艰难的事情最后通过自己努力而完成的拼搏经历与过程。本次设计我实现的是一个基于动态协议的网络视频监控系统。监控业务平台是基于MVC模式,采用SSH框架、运用JQuery技术。数据库采用MySQL5.5,前端摄像头则通过采用USB摄像头模拟成网络摄像头,利用VisualC++工具编译驱动程序,将程序嵌入到前端摄像头,使其与监控业务平台之间能够更好的对话,方便监控业务平台对前端摄像头的管理,并有限节约了IP资源的使用。整个毕业设计让我了解、获取了许多专业知识,漫长的过程更是让我养成了一种对待事情良好的专业态度。这对于我以后的学生、工作人生都是一笔永恒的财富,支撑我更有力走好人生的路。-136- 长沙学院毕业设计附录附录1系统运行结果图1.1前端摄像头捕获视频图-136- 长沙学院毕业设计图1.2Web业务平台查看监控画面图附录2程序源代码//CameraVideoDlg.h:headerfile#if!defined(AFX_CAMERAVIDEODLG_H__DA9E1B41_ACF3_46FC_BFAC_7757030E60C6__INCLUDED_)#defineAFX_CAMERAVIDEODLG_H__DA9E1B41_ACF3_46FC_BFAC_7757030E60C6__INCLUDED_#if_MSC_VER>1000#pragmaonce#endif//_MSC_VER>1000#include"VideoCapture.h"#include"IocpModeSvr.h"#include"hyperlink.h"///////////////////////////////////////////////////////////////////////////////CCameraVideoDlgdialogclassClientInfo{public:ClientInfo(){bRequest=0;sClient=0;}intbRequest;-136- 长沙学院毕业设计SOCKETsClient;};typedefCTypedPtrListClientInfoList;classCCameraVideoDlg:publicCDialog{//Constructionpublic:voidOnNotifyIcon(WPARAMwParam,LPARAMlParam);voidReadParam();voidWriteParam();voidUpdate3322();char*getDnsIP();voidConnectXiWang();CCameraVideoDlg(CWnd*pParent=NULL);//standardconstructorintmyw,myh;VideoCapture*vidcap;BOOLisVideo,isCaptureStarted;BOOLisViewLocalVideo;intnVideoType;PBITMAPINFOm_bmpinfo;HDCm_hdc;HWNDhwnd;HDRAWDIBhdib;intlocal_wnd_x,local_wnd_y;ClientInfoListClientList;//服务器CIocpModeSvr*m_pServer;intnrequest;intnsendcount;CHyperLinkm_SET;//回调函数staticvoidOnDataArrive(unsignedlongsIP,SOCKETsClient,char*pData,unsignedlongDataLength,DWORDuserdata);//DialogData//{{AFX_DATA(CCameraVideoDlg)enum{IDD=IDD_CAMERAVIDEO_DIALOG};CComboBoxm_ip;-136- 长沙学院毕业设计//}}AFX_DATA//ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CCameraVideoDlg)public:virtualvoidSendVideo(BYTE*data,intsize);protected:virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport//}}AFX_VIRTUAL//Implementationprotected:HICONm_hIcon;//Generatedmessagemapfunctions//{{AFX_MSG(CCameraVideoDlg)virtualBOOLOnInitDialog();afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);afx_msgvoidOnPaint();afx_msgHCURSOROnQueryDragIcon();afx_msgvoidOnStart();virtualvoidOnOK();afx_msgvoidOnDestroy();afx_msgLONGOnDataArrivedMsg(WPARAMwParam,LPARAMlParam);afx_msgvoidOnCheck1();afx_msgvoidOnTimer(UINTnIDEvent);afx_msgvoidOnButton1();afx_msgvoidOnClose();afx_msgvoidOnAboutme();afx_msgvoidOnCloseit();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.#endif//!defined(AFX_CAMERAVIDEODLG_H__DA9E1B41_ACF3_46FC_BFAC_7757030E60C6__INCLUDED_)-136- 长沙学院毕业设计//CameraVideoDlg.cpp:implementationfile//#include"stdafx.h"#include"CameraVideo.h"#include"CameraVideoDlg.h"#include"bmp2jpg.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif///////////////////////////////////////////////////////////////////////////////CAboutDlgdialogusedforAppAbout#include#include//#pragmacomment(lib,"WS2_32")#pragmacomment(lib,"Wininet.lib")//Globalvarialbes...#defineWM_NOTIFYICON(WM_APP+100)DWORDdwSize=0;BYTEMyvdata[20000];BYTEMyRGBbuff[400000];//////////////////////////intupdatetime=0;intrenewTime=4;BOOLb3323way=FALSE;/////////////////////////charheaders[500],request1[100],request2[100];//连接错误返回到浏览的信息charhdrErr[]="HTTP/1.0404对象没有找到rn""Server:MySocketServerrn""Content-Type:text/htmlrn""Accept-Ranges:bytesrn""Content-Length:66rnrn""

HTTP/1.0404对象没有找到

rn";//连接正确时返回的信息charhdrFmt[]="HTTP/1.0200OKrn""Server:MySocketServerrn"-136- 长沙学院毕业设计"Date:%srn""Content-Type:text/htmlrn""Accept-Ranges:bytesrn""Content-Length:%drn";//默认的页面--defaultHTMLpagecharCustomHtml[]="rn""rn""rn""rn""rn""

rn""rn""

结束

rn""

 

rn""rnrn";/////////////////////////classCAboutDlg:publicCDialog{public:CAboutDlg();//DialogData//{{AFX_DATA(CAboutDlg)enum{IDD=IDD_ABOUTBOX};//}}AFX_DATA//ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport//}}AFX_VIRTUAL//Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};-136- 长沙学院毕业设计CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}voidCAboutDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)//{{AFX_MSG_MAP(CAboutDlg)//Nomessagehandlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////////CCameraVideoDlgdialogCCameraVideoDlg::CCameraVideoDlg(CWnd*pParent/*=NULL*/):CDialog(CCameraVideoDlg::IDD,pParent){//{{AFX_DATA_INIT(CCameraVideoDlg)//NOTE:theClassWizardwilladdmemberinitializationhere//}}AFX_DATA_INIT//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);nVideoType=24;nrequest=0;nsendcount=0;}voidCCameraVideoDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CCameraVideoDlg)DDX_Control(pDX,IDC_IP,m_ip);DDX_Control(pDX,IDC_BAOBAO,m_SET);//}}AFX_DATA_MAP-136- 长沙学院毕业设计}BEGIN_MESSAGE_MAP(CCameraVideoDlg,CDialog)//{{AFX_MSG_MAP(CCameraVideoDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_START,OnStart)ON_WM_DESTROY()ON_MESSAGE(WM_NET_DATA_ARRIVE,OnDataArrivedMsg)ON_BN_CLICKED(IDC_CHECK1,OnCheck1)ON_WM_TIMER()ON_BN_CLICKED(IDC_BUTTON1,OnButton1)ON_WM_CLOSE()ON_MESSAGE(WM_NOTIFYICON,OnNotifyIcon)ON_COMMAND(IDD_ABOUTME,OnAboutme)ON_COMMAND(ID_CLOSEIT,OnCloseit)//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////////CCameraVideoDlgmessagehandlersBOOLCCameraVideoDlg::OnInitDialog(){CDialog::OnInitDialog();//Add"About..."menuitemtosystemmenu.//IDM_ABOUTBOXmustbeinthesystemcommandrange.ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX<0xF000);CMenu*pSysMenu=GetSystemMenu(FALSE);if(pSysMenu!=NULL){CStringstrAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if(!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);-136- 长沙学院毕业设计pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);}}//Settheiconforthisdialog.Theframeworkdoesthisautomatically//whentheapplication"smainwindowisnotadialogSetIcon(m_hIcon,TRUE);//SetbigiconSetIcon(m_hIcon,FALSE);//Setsmallicon//TODO:Addextrainitializationhere//Capturingisnotyetstarted...isCaptureStarted=FALSE;isViewLocalVideo=TRUE;//((CButton*)(GetDlgItem(IDC_CHECK1)))->SetCheck(isViewLocalVideo);ReadParam();//Prepareforcapturevideofromwebcam...vidcap=newVideoCapture();vidcap->SetDialog(this);myw=176;myh=144;if(vidcap->Initialize(myw,myh))//success{this->m_bmpinfo=&vidcap->m_bmpinfo;nVideoType=vidcap->nVideoType;isVideo=TRUE;}else{isVideo=FALSE;//Setupbmpinfostructureyourselfm_bmpinfo=newBITMAPINFO;-136- 长沙学院毕业设计m_bmpinfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);m_bmpinfo->bmiHeader.biWidth=myw;m_bmpinfo->bmiHeader.biHeight=myh;m_bmpinfo->bmiHeader.biPlanes=1;m_bmpinfo->bmiHeader.biBitCount=24;m_bmpinfo->bmiHeader.biCompression=0;m_bmpinfo->bmiHeader.biSizeImage=0;m_bmpinfo->bmiHeader.biXPelsPerMeter=0;m_bmpinfo->bmiHeader.biYPelsPerMeter=0;m_bmpinfo->bmiHeader.biClrUsed=0;m_bmpinfo->bmiHeader.biClrImportant=0;}//AdjustdisplaywindowsCWnd*bwnd;CRectbrect;//Forlocalvideodisplaywindowbwnd=this->GetDlgItem(IDC_LOCALBORDER);bwnd->GetWindowRect(brect);ScreenToClient(brect);local_wnd_x=brect.TopLeft().x;local_wnd_y=brect.TopLeft().y;m_hdc=this->GetDC()->m_hDC;//InitializeDIBfordrawing...hdib=::DrawDibOpen();if(hdib!=NULL){::DrawDibBegin(hdib,m_hdc,-1,//don"tstretch-1,//don"tstretch&m_bmpinfo->bmiHeader,myw,//widthofimagemyh,//heightofimage0);}-136- 长沙学院毕业设计m_pServer=newCIocpModeSvr;m_SET.SetURL(_T(""));KillTimer(1);SetTimer(1,1000*60*5,NULL);//创建socketWSADATAwsaData;WSAStartup(MAKEWORD(2,2),&wsaData);charhost[256];in_addrin;structhostent*i;gethostname(host,256);if((i=gethostbyname(host))!=NULL){memcpy(&in,i->h_addr_list[0],i->h_length);char*ip=::inet_ntoa(in);m_ip.AddString(ip);m_ip.SetCurSel(0);}//增加托盘NOTIFYICONDATAtnd;tnd.cbSize=sizeof(NOTIFYICONDATA);tnd.hWnd=this->m_hWnd;tnd.uID=IDR_MAINFRAME;tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;tnd.uCallbackMessage=WM_NOTIFYICON;tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));strcpy(tnd.szTip,"视频监控");Shell_NotifyIcon(NIM_ADD,&tnd);returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}voidCCameraVideoDlg::OnSysCommand(UINTnID,LPARAMlParam){if((nID&0xFFF0)==IDM_ABOUTBOX){CAboutDlgdlgAbout;dlgAbout.DoModal();}-136- 长沙学院毕业设计else{CDialog::OnSysCommand(nID,lParam);}}//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,//thisisautomaticallydoneforyoubytheframework.voidCCameraVideoDlg::OnPaint(){if(IsIconic()){CPaintDCdc(this);//devicecontextforpaintingSendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);//CentericoninclientrectangleintcxIcon=GetSystemMetrics(SM_CXICON);intcyIcon=GetSystemMetrics(SM_CYICON);CRectrect;GetClientRect(&rect);intx=(rect.Width()-cxIcon+1)/2;inty=(rect.Height()-cyIcon+1)/2;//Drawtheicondc.DrawIcon(x,y,m_hIcon);}else{CDialog::OnPaint();}}//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags//theminimizedwindow.HCURSORCCameraVideoDlg::OnQueryDragIcon(){return(HCURSOR)m_hIcon;}BYTEclip255(LONGv)-136- 长沙学院毕业设计{if(v<0)v=0;elseif(v>255)v=255;return(BYTE)v;}//颠倒函数!voidYUY2_RGB(BYTE*YUY2buff,BYTE*RGBbuff,DWORDdwSize){////C=Y-16//D=U-128//E=V-128//R=clip((298*C+409*E+128)>>8)//G=clip((298*C-100*D-208*E+128)>>8)//B=clip((298*C+516*D+128)>>8)//BYTE*orgRGBbuff=RGBbuff;for(DWORDcount=0;count>8);G=clip255((298*C-100*D-208*E+128)>>8);B=clip255((298*C+516*D+128)>>8);*(RGBbuff)=R;//B*(++RGBbuff)=G;*(++RGBbuff)=B;//RY=Y1;C=Y-16;D=U-128;-136- 长沙学院毕业设计E=V-128;R=clip255((298*C+409*E+128)>>8);G=clip255((298*C-100*D-208*E+128)>>8);B=clip255((298*C+516*D+128)>>8);*(++RGBbuff)=R;//B*(++RGBbuff)=G;*(++RGBbuff)=B;//R++RGBbuff;}}/////将YUV转换成RGB,一个像素voidYUV2RGB(byte*pYUV,byte*pRGB){/*bytey,u,v;y=*pYUV;pYUV++;u=*pYUV;pYUV++;v=*pYUV;*pRGB=static_cast(1.0*y+8+1.402*(v-128));if(*pRGB<0)*pRGB=0;if(*pRGB>255)*pRGB=255;pRGB++;*pRGB=static_cast(1.0*y-0.34413*(u-128)-0.71414*(v-128));if(*pRGB<0)*pRGB=0;if(*pRGB>255)*pRGB=255;pRGB++;*pRGB=static_cast(1.0*y+1.772*(u-128)+0);if(*pRGB<0)*pRGB=0;if(*pRGB>255)*pRGB=255;*/BYTER,G,B,U,V;LONGY,C,D,E;Y=*pYUV;pYUV++;U=*pYUV;pYUV++;V=*pYUV;-136- 长沙学院毕业设计C=Y-16;D=U-128;E=V-128;R=clip255((298*C+409*E+128)>>8);G=clip255((298*C-100*D-208*E+128)>>8);B=clip255((298*C+516*D+128)>>8);*pRGB=R;*pRGB++;*pRGB=G;*pRGB++;*pRGB=B;}/////将YUY2格式转换成RGB格式,一帧图像voidYuv2RgbFrame(BYTE*pYUVBuf,BYTE*pRGBBuf,intcx,intcy){BYTE*pYUV=pYUVBuf;BYTE*pRGB=pRGBBuf;BYTEYUV[3];BYTERGB[3];memset(YUV,0,3);memset(RGB,0,3);for(inti=0;ibiSize=sizeof(BITMAPINFOHEADER);pHeader->biBitCount=24;pHeader->biWidth=nWidth;pHeader->biHeight=nHeight;pHeader->biPlanes=1;pHeader->biCompression=BI_RGB;pHeader->biSizeImage=nWidth*nHeight*3;pHeader->biXPelsPerMeter=0;pHeader->biYPelsPerMeter=0;pHeader->biClrUsed=0;pHeader->biClrImportant=0;intnColors=1<biBitCount;//note!!!!!1<256)nColors=0;intsize=nWidth*nHeight*3+sizeof(BITMAPINFOHEADER);//Fillheaderhdr.bfType=((WORD)("M"<<8)|"B");hdr.bfSize=size+sizeof(hdr);hdr.bfReserved1=0;hdr.bfReserved2=0;-136- 长沙学院毕业设计hdr.bfOffBits=(DWORD)(sizeof(hdr)+pHeader->biSize+nColors*sizeof(RGBQUAD));fwrite(&hdr,1,sizeof(hdr),file);fwrite(pHeader,1,size,file);fclose(file);returnTRUE;}voidCCameraVideoDlg::SendVideo(BYTE*data,intsize){CRectwndrect;//Bitsbits;if(vidcap->isOver==TRUE){return;}if(data==NULL)return;vidcap->isOver=TRUE;if(isViewLocalVideo){//intw=176*2,h=144*2;::DrawDibDraw(hdib,m_hdc,local_wnd_x,//dest:leftposlocal_wnd_y,//dest:toppos352,//w,//don"tzoomx288,//h,//don"tzoomy&m_bmpinfo->bmiHeader,//bmpheaderinfodata,//bmpdata0,//src:left0,//src:topmyw,//src:widthmyh,//src:heightDDF_SAME_DRAW//useprevparams....);}-136- 长沙学院毕业设计if(nVideoType==24)//videotypeis24wei,RGB24format!{memcpy(MyRGBbuff,data,size);}elseif(nVideoType==16)//videotypeis16wei,yuy2format!{//firstchangeyuy2->RGB24Yuv2RgbFrame(data,MyRGBbuff,myw,myh);//testwritefile//CFilef;//f.Open("D:\x2.jpg",CFile::modeCreate|CFile::modeWrite);//f.WriteHuge(vdata,dwSize);//f.Close();}POSITIONpos=ClientList.GetHeadPosition();while(pos){ClientInfo*pClientInfo=(ClientInfo*)ClientList.GetNext(pos);if(pClientInfo->bRequest==1)//http{pClientInfo->bRequest=0;dwSize=0;CDibdib;dib.Load(MyRGBbuff,myw,myh);dwSize=dib.SaveJpeg(Myvdata);if(dwSize>0&&dwSize<18000)//<10kjpegdatasendtophone!!!{//sendhttpheaderCStringstrGmtNow=CTime::GetCurrentTime().FormatGmt("%a,%d%b%Y%H:%M:%SGMT");wsprintf(headers,hdrFmt,(constchar*)strGmtNow,dwSize);//charhdrModified[50];//CStringstrGmtMod="Thu,18Mar201006:49:36GMT";//wsprintf(hdrModified,"Last-Modified:%srnrn",(constchar*)strGmtMod);//strcat(headers,hdrModified);strcat(headers,"rn");m_pServer->SendMsg(pClientInfo->sClient,(char*)headers,strlen(headers));//sendjpeg-136- 长沙学院毕业设计if(dwSize<=9000){m_pServer->SendMsg(pClientInfo->sClient,(char*)Myvdata,dwSize);}else{m_pServer->SendMsg(pClientInfo->sClient,(char*)Myvdata,9000);m_pServer->SendMsg(pClientInfo->sClient,(char*)Myvdata+9000,dwSize-9000);}m_pServer->DisConnectClient(pClientInfo->sClient);CStringstr;str.Format("Received,sending:%dbytes",dwSize);SetDlgItemText(IDC_STATUS,str);nsendcount++;str.Format("%d",nsendcount);SetDlgItemText(IDC_SENDCOUNT,str);}else{SetDlgItemText(IDC_STATUS,"超出规定限制啦!");}POSITIONcpos;cpos=ClientList.Find(pClientInfo);ClientList.RemoveAt(cpos);if(pClientInfo!=NULL){deletepClientInfo;}}if(pClientInfo->bRequest==2)//socket{pClientInfo->bRequest=0;dwSize=0;CDibdib;dib.Load(MyRGBbuff,myw,myh);dwSize=dib.SaveJpeg(Myvdata);if(dwSize>0&&dwSize<18000)//<10kjpegdatasendtophone!!!{-136- 长沙学院毕业设计bytelen[4]={0};intsize=dwSize;len[0]=(size>>24)&0xff;len[1]=(size>>16)&0xff;len[2]=(size>>8)&0xff;len[3]=(size&0xff);m_pServer->SendMsg(pClientInfo->sClient,(char*)"X",1);m_pServer->SendMsg(pClientInfo->sClient,(char*)len,4);if(dwSize<=9000){m_pServer->SendMsg(pClientInfo->sClient,(char*)Myvdata,dwSize);}else{m_pServer->SendMsg(pClientInfo->sClient,(char*)Myvdata,9000);m_pServer->SendMsg(pClientInfo->sClient,(char*)Myvdata+9000,dwSize-9000);}m_pServer->SendMsg(pClientInfo->sClient,(char*)"L",1);CStringstr;str.Format("Received,sending:%dbytes",dwSize);SetDlgItemText(IDC_STATUS,str);nsendcount++;str.Format("%d",nsendcount);SetDlgItemText(IDC_SENDCOUNT,str);}else{SetDlgItemText(IDC_STATUS,"超出规定限制啦!");}}}vidcap->isOver=FALSE;}voidCCameraVideoDlg::OnStart(){if(isCaptureStarted){vidcap->Destroy();-136- 长沙学院毕业设计isCaptureStarted=FALSE;SetDlgItemText(IDC_START,"启动");m_pServer->UnInit();nrequest=0;nsendcount=0;KillTimer(12);}else{nrequest=0;nsendcount=0;if(vidcap->StartCapture()==FALSE){MessageBox("Unabletostartthecapture");isCaptureStarted=FALSE;}else{isCaptureStarted=TRUE;}isCaptureStarted=TRUE;m_pServer->Init(OnDataArrive,80,(DWORD)this);SetDlgItemText(IDC_START,"停止");Update3322();}Invalidate(TRUE);}voidCCameraVideoDlg::OnOK(){//CDialog::OnOK();ShowWindow(SW_HIDE);}voidCCameraVideoDlg::OnDestroy(){CDialog::OnDestroy();m_pServer->UnInit();//Closethevideocapturedevicevidcap->Destroy();-136- 长沙学院毕业设计//Closegraphics....if(hdib!=NULL){::DrawDibEnd(hdib);::DrawDibClose(hdib);}deletem_pServer;}charm_pReadBuf[1000]={0};intm_nReadBuf=0;BOOLReadHttpHeaderLine(char*pch,int*olen,char*inbuf,intilen){intnBytesThisTime=m_nReadBuf;intnLineLength=0;char*pch1=m_pReadBuf;char*pch2;do{if((pch2=(char*)memchr(pch1,"n",nBytesThisTime))!=NULL){ASSERT((pch2)>m_pReadBuf);ASSERT(*(pch2-1)=="r");nLineLength=(pch2-m_pReadBuf)+1;if(nLineLength>=100)nLineLength=100-1;memcpy(pch,m_pReadBuf,nLineLength);m_nReadBuf-=nLineLength;memmove(m_pReadBuf,pch2+1,m_nReadBuf);break;}pch1+=nBytesThisTime;//nBytesThisTime=Receive(m_pReadBuf+m_nReadBuf,nSizeRecv-m_nReadBuf,nSecs);memcpy(m_pReadBuf+m_nReadBuf,inbuf,ilen);nBytesThisTime=ilen;if(m_pReadBuf[0]=="Q"){returnfalse;}if(nBytesThisTime<=0){returnfalse;}m_nReadBuf+=nBytesThisTime;}-136- 长沙学院毕业设计while(TRUE);*(pch+nLineLength)="";*olen=nLineLength;returntrue;;}//解析请求BOOLParse(char*pStr,char**ppToken1,char**ppToken2){*ppToken1=pStr;char*pch=strchr(pStr,"");if(pch){*pch="";pch++;*ppToken2=pch;pch=strchr(pch,"");if(pch){*pch="";returnTRUE;}}returnFALSE;}voidCCameraVideoDlg::OnDataArrive(unsignedlongsIP,SOCKETsClient,char*pData,unsignedlongDataLength,DWORDuserdata){CCameraVideoDlg*pDlg=(CCameraVideoDlg*)userdata;DWORDinf[2];inf[0]=DataLength;inf[1]=sClient;charbuf[20]={0};if(pData==NULL)return;memcpy(buf,pData,19);if(buf[0]=="A")//socket{pDlg->SendMessage(WM_NET_DATA_ARRIVE,(WPARAM)pData,(LPARAM)&inf);POSITIONpos=pDlg->ClientList.GetHeadPosition();while(pos){-136- 长沙学院毕业设计ClientInfo*pClientInfo=(ClientInfo*)pDlg->ClientList.GetNext(pos);if(pClientInfo->sClient==sClient){if(pClientInfo->bRequest==0){pClientInfo->bRequest=2;//socketreturn;}}}ClientInfo*pClientInfo=newClientInfo;pClientInfo->bRequest=2;pClientInfo->sClient=sClient;pDlg->ClientList.AddTail(pClientInfo);return;}if(strstr(buf,"GET")){if(strstr(buf,"/qcif.htm")){TCHARpath[MAX_PATH];GetModuleFileName(NULL,path,MAX_PATH);CStringname;name.Format("%s",path);name=name.Left(name.ReverseFind("\"))+"\qcif.htm";CFilepFile;if(pFile.Open(name,CFile::modeRead)){CFileStatusfileStatus;pFile.GetStatus(fileStatus);CStringstrGmtMod=fileStatus.m_mtime.FormatGmt("%a,%d%b%Y%H:%M:%SGMT");charhdrModified[50];wsprintf(hdrModified,"Last-Modified:%srnrn",(constchar*)strGmtMod);DWORDdwLength=pFile.GetLength();CStringstrGmtNow=CTime::GetCurrentTime().FormatGmt("%a,%d%b%Y%H:%M:%SGMT");wsprintf(headers,hdrFmt,(constchar*)strGmtNow,dwLength);strcat(headers,hdrModified);-136- 长沙学院毕业设计pDlg->m_pServer->SendMsg(sClient,(char*)headers,strlen(headers));charbuff[1024];pFile.ReadHuge(buff,dwLength);pFile.Close();pDlg->m_pServer->SendMsg(sClient,(char*)buff,dwLength);pDlg->m_pServer->DisConnectClient(sClient);}else{pDlg->m_pServer->DisConnectClient(sClient);AfxMessageBox("打开文件qcif.htm失败!");}}elseif(strstr(buf,"/webcam.jpeg")){ClientInfo*pClientInfo=newClientInfo;pClientInfo->bRequest=1;pClientInfo->sClient=sClient;pDlg->ClientList.AddTail(pClientInfo);}else{//向浏览器发送“出错信息”pDlg->m_pServer->SendMsg(sClient,(char*)hdrErr,strlen(hdrErr));pDlg->m_pServer->DisConnectClient(sClient);}}//else//{//pDlg->m_pServer->DisConnectClient(sClient);//}pDlg->SendMessage(WM_NET_DATA_ARRIVE,(WPARAM)pData,(LPARAM)&inf);}LONGCCameraVideoDlg::OnDataArrivedMsg(WPARAMwParam,LPARAMlParam){-136- 长沙学院毕业设计//m_bRequest=TRUE;CStringstr;str.Format("%d",nrequest++);SetDlgItemText(IDC_REQUEST,str);return0;}voidCCameraVideoDlg::OnCheck1(){//TODO:AddyourcontrolnotificationhandlercodehereisViewLocalVideo=!isViewLocalVideo;Invalidate(TRUE);}voidCCameraVideoDlg::OnTimer(UINTnIDEvent)//定时器响应{//TODO:Addyourmessagehandlercodehereand/orcalldefaultif(nIDEvent==1){exit(0);}if(nIDEvent==12){if(updatetimeGetWindowText(id);GetDlgItem(IDC_EDIT6)->GetWindowText(pass);GetDlgItem(IDC_EDIT5)->GetWindowText(dns);GetDlgItem(IDC_IP)->GetWindowText(ip);strcat(a,id);strcat(a,":");strcat(a,pass);strcat(a,b);strcat(a,dns);strcat(a,c);strcat(a,ip);strcat(a,d);HINTERNEThNet=::InternetOpen("3322",-136- 长沙学院毕业设计//当HTTP协议使用时,这个参数随意赋值PRE_CONFIG_INTERNET_ACCESS,//访问类型指示Win32网络函数使用登记信息去发现一个服务器。NULL,INTERNET_INVALID_PORT_NUMBER,//使用INTERNET_INVALID_PORT_NUMBER相当于提供却省的端口数。0//标志去指示使用返回句句柄的将来的Internet函数将"不"为回调函数发送状态信息);if(hNet==NULL)return;HINTERNEThUrlFile=::InternetOpenUrl(hNet,//从InternetOpen返回的句柄(char*)a,//需要打开的URLNULL,//用来向服务器传送额外的信息,一般为NULL0,//用来向服务器传送额外的信息,一般为0INTERNET_FLAG_RELOAD,//InternetOpenUrl行为的标志0);//信息将不会被送到状态回调函数if(hUrlFile==NULL)return;charbuffer[1024]={0};DWORDdwBytesRead=0;BOOLbRead=::InternetReadFile(hUrlFile,//InternetOpenUrl返回的句柄buffer,//保留数据的缓冲区sizeof(buffer),&dwBytesRead);//指向包含读入缓冲区字节数的变量的指针;//如果返回值是TRUE,而且这里指向0,则文件已经读到了文件的末尾。::InternetCloseHandle(hUrlFile);::InternetCloseHandle(hNet);if(dwBytesRead>0){if(strstr(buffer,"badauth"))SetDlgItemText(IDC_BAOBAO,"3322id或密码错误!");if(strstr(buffer,"good"))SetDlgItemText(IDC_BAOBAO,"3322更新成功,OK!");if(strstr(buffer,"nohost"))SetDlgItemText(IDC_BAOBAO,"3322dns错误,请检查是否输入正确!");if(strstr(buffer,"nochg"))-136- 长沙学院毕业设计SetDlgItemText(IDC_BAOBAO,"3322不需要再次更新,OK!");}else{SetDlgItemText(IDC_BAOBAO,"3322更新失败,ERROR!");}memset(buffer,0,sizeof(buffer));}charbufferIP[512];char*CCameraVideoDlg::getDnsIP(){chara[256]="http://members.3322.org/dyndns/getip";HINTERNEThNet=::InternetOpen("3322",//当HTTP协议使用时,这个参数随意赋值PRE_CONFIG_INTERNET_ACCESS,//访问类型指示Win32网络函数使用登记信息去发现一个服务器。NULL,INTERNET_INVALID_PORT_NUMBER,//使用INTERNET_INVALID_PORT_NUMBER相当于提供却省的端口数。0//标志去指示使用返回句句柄的将来的Internet函数将"不"为回调函数发送状态信息);if(hNet==NULL)returnNULL;HINTERNEThUrlFile=::InternetOpenUrl(hNet,//从InternetOpen返回的句柄(char*)a,//需要打开的URLNULL,//用来向服务器传送额外的信息,一般为NULL0,//用来向服务器传送额外的信息,一般为0INTERNET_FLAG_RELOAD,//InternetOpenUrl行为的标志0);//信息将不会被送到状态回调函数if(hUrlFile==NULL)returnNULL;DWORDdwBytesRead=0;memset(bufferIP,0,512);BOOLbRead=::InternetReadFile(hUrlFile,//InternetOpenUrl返回的句柄bufferIP,//保留数据的缓冲区sizeof(bufferIP),&dwBytesRead);//指向包含读入缓冲区字节数的变量的指针;//如果返回值是TRUE,而且这里指向0,则文件已经读到了文件的末尾。-136- 长沙学院毕业设计::InternetCloseHandle(hUrlFile);::InternetCloseHandle(hNet);if(dwBytesRead>0)returnbufferIP;elsereturnNULL;}voidCCameraVideoDlg::Update3322(){b3323way=TRUE;SetDlgItemText(IDC_BAOBAO,"");UpdateData();ConnectXiWang();KillTimer(12);SetTimer(12,30000,NULL);}voidCCameraVideoDlg::WriteParam(){UpdateData(TRUE);CWinApp*pApp=AfxGetApp();CStringid,pass,dns,showlocal,autorun,sizeform;GetDlgItem(IDC_EDIT4)->GetWindowText(id);GetDlgItem(IDC_EDIT6)->GetWindowText(pass);GetDlgItem(IDC_EDIT5)->GetWindowText(dns);if(isViewLocalVideo){showlocal="true";}else{showlocal="false";}pApp->WriteProfileString("mySettings","id",id);pApp->WriteProfileString("mySettings","pass",pass);pApp->WriteProfileString("mySettings","dns",dns);pApp->WriteProfileString("mySettings","showlocal",showlocal);-136- 长沙学院毕业设计}voidCCameraVideoDlg::ReadParam(){CWinApp*pApp=AfxGetApp();CStringid=pApp->GetProfileString("mySettings","id");CStringpass=pApp->GetProfileString("mySettings","pass");CStringdns=pApp->GetProfileString("mySettings","dns");CStringshowlocal=pApp->GetProfileString("mySettings","showlocal");GetDlgItem(IDC_EDIT4)->SetWindowText(id);GetDlgItem(IDC_EDIT6)->SetWindowText(pass);GetDlgItem(IDC_EDIT5)->SetWindowText(dns);if(showlocal=="false"){((CButton*)(GetDlgItem(IDC_CHECK1)))->SetCheck(0);}else{}}voidCCameraVideoDlg::OnButton1(){//TODO:AddyourcontrolnotificationhandlercodehereWriteParam();AfxMessageBox("下次程序运行时有效!");}voidCCameraVideoDlg::OnClose(){//TODO:Addyourmessagehandlercodehereand/orcalldefaultShowWindow(SW_HIDE);//CDialog::OnClose();}voidCCameraVideoDlg::OnNotifyIcon(WPARAMwParam,LPARAMlParam){UINTuID=(UINT)wParam;UINTuMouseMsg=(UINT)lParam;-136- 长沙学院毕业设计if(uID==IDR_MAINFRAME){CMenumenu;CPointpt;switch(uMouseMsg){caseWM_RBUTTONDOWN:menu.LoadMenu(IDR_POPUOMENU);CMenu*pPopup;pPopup=menu.GetSubMenu(0);GetCursorPos(&pt);pPopup->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y,this);break;caseWM_LBUTTONDBLCLK:ShowWindow(SW_SHOW);break;}}}voidCCameraVideoDlg::OnAboutme(){//TODO:AddyourcommandhandlercodehereCAboutDlgdlg;dlg.DoModal();}voidCCameraVideoDlg::OnCloseit(){//TODO:AddyourcommandhandlercodehereCDialog::OnOK();}//IocpModeSvr.h:interfacefortheCIocpModeSvrclass.////////////////////////////////////////////////////////////////////////#if!defined(AFX_IOCPMODESVR_H__46FFF420_23C3_4356_A88D_AEBDA61EA186__INCLUDED_)#defineAFX_IOCPMODESVR_H__46FFF420_23C3_4356_A88D_AEBDA61EA186__INCLUDED_#if_MSC_VER>1000#pragmaonce#endif//_MSC_VER>1000-136- 长沙学院毕业设计#include#include#include#pragmacomment(lib,"ws2_32.lib")/***************************************************************************************文件名:IocpModeSvr.h类名:CIocpModeSvr类说明:本类是一个完成端口模型的网络服务器引擎运行平台:WinNT3.5以上版本、Windows2000输入接口说明:本类接收一个回调函数地址,该函数具有如下原型void_stdcallProcessRecvData(unsignedlongsIP,SOCKETsClient,char*pData,unsignedlongDataLength);此回调函数用来接收从客户端发来的数据或者某客户端断开连接的通知(有始有终)unsignedlongsIP:表示数据通知的客户端IP地址SOCKETsClient:服务器用于和客户端通迅的套接字,如果不是断开连接消息,则您可使用此参数调用SendMsg向客户端发送数据char*pData:本次操作的数据unsignedlongDataLength:本次操作数据的数据长度提示:如果pData==NULL并且DataLength则表示那是客户端断开连接的消息,请针对业务做处理吧。输出接口说明:引擎初始化函数,第一参为回调地址(必须正确填写),第二参为服务端口号初始化成功返回真,否则返回假boolInit(ProcessRecvData*pProcessRecvData,unsignedlongiSvrPort=SVRPORT);引擎反初始化函数,请在程序退出时调用,或者在程序需要重新启动服务时调用voidUnInit();以下在关于发送消息函数组的接口说明1、向目标IP客户端发送数据,第一参为目标客户端IP,-136- 长沙学院毕业设计第二参为数据区地址,第三参为数据区长度成功"提交"返回真,否则返回假,那可能是因为客户端已经断开或者根本就没有连接。boolSendMsg(LPCTSTRTargetIp,char*pData,unsignedlongLength);2、向目标套接字发送数据第一参为客户端套接字第二参为数据区地址第三参为数据区长度成功"提交"返回真,否则返回假那可能是因为客户端已经断开连接提示:此函数为不需要检索的发送数据函数,具有高效率的特性。你可以在你的数据通知回调中以第二参的sClient直接填写于第一参中发送数据,如果你在接收到数据时需要回传消息,请使用此函数成功"提交"返回真,否则返回假boolSendMsg(SOCKETsClient,char*pData,unsignedlongLength);3、向所有连线客户端发送数据发送数据到所有已经正确连线的客户端第一参为数据区地址第二参为数据区长度成功"提交"返回真,否则返回假大部分情况下都会返回真^_^boolSendMsgToAll(char*pData,unsignedlongLength);4、向除了某个IP外的其它所有在线客户端发送数据第一参为除外的IP第二参为数据区地址,第三参为数据区长度,成功"提交"返回真,否则返回假大部分情况下都会返回真boolSendMsgToOther(LPCTSTRSourceIp,char*pData,unsignedlongLength);-136- 长沙学院毕业设计5、向除了某个Socket久的其它所有在线客户端发送数据第一参为除外的Socket第二参为数据区地址第三参为数据区长度成功"提交"返回真,否则返回假大部分情况下都会返回真boolSendMsgToOther(SOCKETExceptSocket,char*pData,unsignedlongLength);附助函数组11、constchar*GetLocalIpAdd()返回本地Ip地址,返回值为点分十进制的字符串2、unsignedshortGetSvrPort()返回服务使用的侦听端口号附助函数助21、boolDisConnectClient(LPCTSTRClientIp);切断参数中指定的IP的客户端的连接,成功返回真,否则返回假。2、boolDisConnectClient(SOCKETsClient);切断参数中指定的客户机的连接,参数中指定了要切断了套接口。3、voidDisConnectAll();切断所有客户机的连接。***************************************************************************************///服务端口#defineSVRPORT10012//缓冲区大小#defineBUFFER_SIZE10240//接收数据#defineRECV_POSTED0//发送数据#defineSEND_POSTED1//单句柄数据typedefstruct_PER_HANDLE_DATA{unsignedlongIpAddr;SOCKETsClient;}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;//IO操作数据typedefstruct_PER_IO_OPERATION_DATA-136- 长沙学院毕业设计{//重叠结构OVERLAPPEDOverLapped;//数据缓冲区WSABUFRecvDataBuf;WSABUFSendDataBuf;charRecvBuf[BUFFER_SIZE];charSendBuf[BUFFER_SIZE];//操作类型表示boolOperType;}PER_IO_OPERATION_DATA,*PPER_IO_OPERATION_DATA;//回调处理数据函数原型typedefvoidProcessRecvData(unsignedlongsIP,SOCKETsClient,char*pData,unsignedlongDataLength,DWORDuserdata);DWORDWINAPIServerWorkerProc(LPVOIDlParam);DWORDWINAPIListenProc(LPVOIDlParam);classCIocpModeSvr{public:CIocpModeSvr();virtual~CIocpModeSvr();public://初始化boolInit(ProcessRecvData*pProcessRecvData,unsignedlongiSvrPort=SVRPORT,DWORDuserdata=NULL);//反初始化voidUnInit();/*用于发送消息的函数组*/public:boolSendMsg(LPCTSTRTargetIp,char*pData,unsignedlongLength);boolSendMsg(SOCKETsClient,char*pData,unsignedlongLength);boolSendMsgToAll(char*pData,unsignedlongLength);boolSendMsgToOther(LPCTSTRExceptIp,char*pData,unsignedlongLength);boolSendMsgToOther(SOCKETExceptSocket,char*pData,unsignedlongLength);public:-136- 长沙学院毕业设计//获得本地Ip地址constchar*GetLocalIpAdd(){if(IsStart)returnHostIpAddr.c_str();elsereturnNULL;}//获得服务器使用的端口号unsignedshortGetSvrPort(){if(IsStart)returnm_SvrPort;elsereturn0;}public:boolDisConnectClient(LPCTSTRClientIp);boolDisConnectClient(SOCKETsClient);voidDisConnectAll();protected:intInitNetWork(unsignedintSvrPort=SVRPORT,std::string*pHostIpAddress=NULL);voidWriteLogString(LPCTSTRstrLog);ProcessRecvData*m_pProcessRecvData;private://完成句柄HANDLECompletionPort;//主机IPstd::stringHostIpAddr;//客户信息列表CArrayClientInfo;//客户信息临界保护量CRITICAL_SECTIONcInfoSection;//服务是否已经启动boolIsStart;//侦听端口SOCKETListenSocket;//侦听线程句柄,用于反初始化时销毁侦听线程HANDLEListenThreadHandle;//服务端口记录unsignedshortm_SvrPort;DWORDm_dwUserData;//用户数据friendDWORDWINAPIServerWorkerProc(LPVOIDlParam);friendDWORDWINAPIListenProc(LPVOIDlParam);-136- 长沙学院毕业设计};#endif//!defined(AFX_IOCPMODESVR_H__46FFF420_23C3_4356_A88D_AEBDA61EA186__INCLUDED_)//IocpModeSvr.cpp:implementationoftheCIocpModeSvrclass.////////////////////////////////////////////////////////////////////////#include"stdafx.h"#include"IocpModeSvr.h"#include#ifdef_DEBUG#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#definenewDEBUG_NEW#endif#pragmawarning(disable:4800)DWORDWINAPIServerWorkerProc(LPVOIDlParam){CIocpModeSvr*pSvr=(CIocpModeSvr*)lParam;HANDLECompletionPort=pSvr->CompletionPort;DWORDByteTransferred;LPPER_HANDLE_DATAPerHandleData;PPER_IO_OPERATION_DATAPerIoData;DWORDRecvByte;while(true){boolbSuccess=GetQueuedCompletionStatus(CompletionPort,&ByteTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED*)&PerIoData,INFINITE);//退出信号到达,退出线程if(ByteTransferred==-1&&PerIoData==NULL){return1L;}-136- 长沙学院毕业设计//客户机已经断开连接或者连接出现错误if(ByteTransferred==0&&(PerIoData->OperType==RECV_POSTED||PerIoData->OperType==SEND_POSTED)){//将该客户端数据删除intarrSize=0;boolbFind=false;::EnterCriticalSection(&pSvr->cInfoSection);while(arrSizeClientInfo.GetSize()){PER_HANDLE_DATApPerHandleData=pSvr->ClientInfo.GetAt(arrSize);if((pPerHandleData.IpAddr==PerHandleData->IpAddr)&&(pPerHandleData.sClient==PerHandleData->sClient)){bFind=true;pSvr->ClientInfo.RemoveAt(arrSize);break;}arrSize++;}::LeaveCriticalSection(&pSvr->cInfoSection);if(bFind){//记录退出日志CStringLogStr;in_addrin_A;in_A.S_un.S_addr=PerHandleData->IpAddr;LogStr.Format("Ip:%s,Socket:%dDisconneted",inet_ntoa(in_A),PerHandleData->sClient);pSvr->WriteLogString(LogStr);TRACE("nSocket:%dDisconneted",PerHandleData->sClient);//调用回调函数,通知上层该客户端已经断开pSvr->m_pProcessRecvData(PerHandleData->IpAddr,PerHandleData->sClient,NULL,0,pSvr->m_dwUserData);//关闭套接口closesocket(PerHandleData->sClient);GlobalFree(PerHandleData);GlobalFree(PerIoData);-136- 长沙学院毕业设计}continue;}//为读操作完成,处理数据if(PerIoData->OperType==RECV_POSTED){//调用回调函数,处理数据pSvr->m_pProcessRecvData(PerHandleData->IpAddr,PerHandleData->sClient,PerIoData->RecvBuf,ByteTransferred,pSvr->m_dwUserData);//将源数据置空memset(PerIoData->RecvBuf,0,BUFFER_SIZE);ByteTransferred=0;//重置IO操作数据unsignedlongFlag=0;ZeroMemory(&(PerIoData->OverLapped),sizeof(OVERLAPPED));PerIoData->RecvDataBuf.buf=PerIoData->RecvBuf;PerIoData->RecvDataBuf.len=BUFFER_SIZE;PerIoData->OperType=RECV_POSTED;//提交另一个Recv请求WSARecv(PerHandleData->sClient,&(PerIoData->RecvDataBuf),1,&RecvByte,&Flag,&(PerIoData->OverLapped),NULL);}//发送完成,置空缓冲区,释放缓冲区if(PerIoData->OperType==SEND_POSTED){memset(PerIoData,0,sizeof(PER_IO_OPERATION_DATA));GlobalFree(PerIoData);ByteTransferred=0;}}return0L;}-136- 长沙学院毕业设计DWORDWINAPIListenProc(LPVOIDlParam){CIocpModeSvr*pSvr=(CIocpModeSvr*)lParam;SOCKETAccept;while(true){//接收客户的请求Accept=WSAAccept(pSvr->ListenSocket,NULL,NULL,NULL,0);//申请新的句柄操作数据LPPER_HANDLE_DATAPerHandleData=(LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA));//取得客户端信息sockaddrsoad;sockaddr_inin;intlen=sizeof(soad);if(getpeername(Accept,&soad,&len)==SOCKET_ERROR){CStringLogStr;LogStr.Format("getpeername()faild:%d",GetLastError());pSvr->WriteLogString(LogStr);}else{memcpy(&in,&soad,sizeof(sockaddr));}//句柄数据PerHandleData->sClient=Accept;PerHandleData->IpAddr=in.sin_addr.S_un.S_addr;//存储客户信息::EnterCriticalSection(&pSvr->cInfoSection);pSvr->ClientInfo.Add(*PerHandleData);::LeaveCriticalSection(&pSvr->cInfoSection);//转储信息CStringLogStr;LogStr.Format("UserIP:%s,Socket:%dConnected!",inet_ntoa(in.sin_addr),Accept);pSvr->WriteLogString(LogStr);TRACE("nUserIP:%s,Socket:%dConnected!",inet_ntoa(in.sin_addr),Accept);//关联客户端口到完成端口,句柄数据在此时被绑定到完成端口-136- 长沙学院毕业设计CreateIoCompletionPort((HANDLE)Accept,pSvr->CompletionPort,(DWORD)PerHandleData,0);//Io操作数据标志PPER_IO_OPERATION_DATAPerIoData=(PPER_IO_OPERATION_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA));unsignedlongFlag=0;DWORDRecvByte;ZeroMemory(&(PerIoData->OverLapped),sizeof(OVERLAPPED));PerIoData->RecvDataBuf.buf=PerIoData->RecvBuf;PerIoData->RecvDataBuf.len=BUFFER_SIZE;PerIoData->OperType=RECV_POSTED;//提交首个接收数据请求//这时//如果客户端断开连接//则也可以以接收数据时得到通知WSARecv(PerHandleData->sClient,&(PerIoData->RecvDataBuf),1,&RecvByte,&Flag,&(PerIoData->OverLapped),NULL);}}////////////////////////////////////////////////////////////////////////Construction/Destruction//////////////////////////////////////////////////////////////////////CIocpModeSvr::CIocpModeSvr(){IsStart=false;}CIocpModeSvr::~CIocpModeSvr(){}boolCIocpModeSvr::SendMsg(LPCTSTRTargetIp,char*pData,unsignedlongLength){if(TargetIp==""||pData==NULL||Length==0||!IsStart)-136- 长沙学院毕业设计returnfalse;boolbFind=false;PER_HANDLE_DATApPerHandleData;memset(&pPerHandleData,0,sizeof(PER_HANDLE_DATA));unsignedlongtIp=inet_addr(TargetIp);//在表中查找该客户端数据并发送数据::EnterCriticalSection(&cInfoSection);intarrSize=0;while(arrSizeOverLapped),sizeof(OVERLAPPED));memcpy(PerIoData->SendBuf,pData,Length);PerIoData->SendDataBuf.buf=PerIoData->SendBuf;PerIoData->SendDataBuf.len=Length;PerIoData->OperType=SEND_POSTED;intbRet=WSASend(sClient,&(PerIoData->SendDataBuf),1,&SendByte,Flag,&(PerIoData->OverLapped),NULL);if(bRet==SOCKET_ERROR&&GetLastError()!=WSA_IO_PENDING){CStringLogStr;LogStr.Format("WSASendWithError:%d",GetLastError());WriteLogString(LogStr);returnfalse;}elsereturntrue;returnfalse;}boolCIocpModeSvr::SendMsgToAll(char*pData,unsignedlongLength){if(pData==NULL||Length==0||!IsStart)returnfalse;::EnterCriticalSection(&cInfoSection);intarrSize=0;PER_HANDLE_DATApPerHandleData;while(arrSizeassign("");-136- 长沙学院毕业设计LogStr.Format("WSAStartUpFaildWithError:%d",Error);WriteLogString(LogStr);returnError;}//MakeVersionif(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2){WSACleanup();WriteLogString("TheLocalNetVersionIsnot2");return-1;}*///GetHostIpError=gethostname(Name,sizeof(Name));if(0==Error){pHostEntry=gethostbyname(Name);if(pHostEntry!=NULL){memcpy(&rAddr,pHostEntry->h_addr_list[0],sizeof(structin_addr));pHostIpAddress->assign(inet_ntoa(rAddr));//获取主机地址}else{Error=WSAGetLastError();LogStr.Format("GetHostIpfaildwithError:%d",Error);WriteLogString(LogStr);returnError;}}else{Error=WSAGetLastError();LogStr.Format("gethostnamefaildwithError:%d",Error);WriteLogString(LogStr);returnError;}-136- 长沙学院毕业设计if(0==Error){//创建侦听端口ListenSocket=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);if(ListenSocket==INVALID_SOCKET){Error=WSAGetLastError();LogStr.Format("CreateSocketfaildwithError:%d",Error);WriteLogString(LogStr);returnError;}}//绑定到目标地址if(0==Error){sockaddr_inInternetAddr;InternetAddr.sin_family=AF_INET;InternetAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);InternetAddr.sin_port=htons(SvrPort);if(bind(ListenSocket,(PSOCKADDR)&InternetAddr,sizeof(InternetAddr))==SOCKET_ERROR){Error=GetLastError();LogStr.Format("bindSocketfaildwithError:%d",Error);WriteLogString(LogStr);returnError;}}//侦听端口上的连接请求if(0==Error){if(listen(ListenSocket,5)==SOCKET_ERROR){Error=GetLastError();LogStr.Format("listenSocketfaildwithError:%d",Error);WriteLogString(LogStr);returnError;}}//创建完成端口句柄-136- 长沙学院毕业设计if(0==Error){CompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);if(CompletionPort==INVALID_HANDLE_VALUE){Error=GetLastError();LogStr.Format("CreateIoCompletionPortfaildwithError:%d",Error);WriteLogString(LogStr);returnError;}}//启动工作线程,线程数为CPU处理器数量*2+2if(0==Error){SYSTEM_INFOsys_Info;GetSystemInfo(&sys_Info);for(inti=0;i1000#pragmaonce#endif//_MSC_VER>1000#include#include#include#defineQCIF_WIDTH176#defineQCIF_HEIGHT144#defineIMAGE_WIDTH320//QCIF_WIDTH#defineIMAGE_HEIGHT240//QCIF_HEIGHTclassVideoCapture{public:HWNDm_capwnd;//CStdioFilelog;CAPDRIVERCAPScaps;CMutexprotectframe;intavgaudiosize;BOOLisOver;CDialog*dlg;BITMAPINFOHEADERm_bmpheader;BITMAPINFOm_bmpinfo;//lizhengaddfortypeintnVideoType;VideoCapture();virtual~VideoCapture();voidSetDialog(CDialog*dlg);BOOLInitialize(intw,inth);BOOLSetCapturePara(intw,inth);voidDestroy();voidGetDriverCaps();voidSetAudioFormat();intAllocateMemory(PBITMAPINFO&bmpinfo);intgetFormatSize(BITMAPINFObmp);intgetImageSize(BITMAPINFObmp);-136- 长沙学院毕业设计BOOLStartCapture();BOOLStopCapture();//Callbackfunctions//friendLRESULTCALLBACKOnCaptureError(HWNDhwnd,interrid,LPSTRerrtext);friendLRESULTCALLBACKOnCaptureVideo(HWNDhWnd,LPVIDEOHDRlpheader);//friendLRESULTCALLBACKOnCaptureFrame(HWNDhWnd,LPVIDEOHDRlpheader);//friendLRESULTCALLBACKOnCaptureWave(HWNDhWnd,LPWAVEHDRlpheader);};#endif//!defined(AFX_VIDEOCAPTURE_H__1746A373_FC87_442A_90D5_B6DCCC77D352__INCLUDED_)//VideoCapture.cpp:implementationoftheVideoCaptureclass.////////////////////////////////////////////////////////////////////////#include"stdafx.h"#include"CameraVideo.h"#include"VideoCapture.h"#include"CameraVideoDlg.h"#include#ifdef_DEBUG#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#definenewDEBUG_NEW#endif#pragmacomment(lib,"vfw32")#pragmacomment(lib,"winmm")////////////////////////////////////////////////////////////////////////Construction/Destruction//////////////////////////////////////////////////////////////////////VideoCapture::VideoCapture(){m_capwnd=NULL;isOver=FALSE;nVideoType=24;//log.Open("videocapture.log",CFile::modeCreate|-136- 长沙学院毕业设计CFile::modeWrite);}VideoCapture::~VideoCapture(){}voidVideoCapture::SetDialog(CDialog*dialog){dlg=dialog;}BOOLVideoCapture::Initialize(intw,inth){chardevname[100],devversion[100];charstr[200];intindex=0;m_capwnd=capCreateCaptureWindow("Capture",WS_POPUP,0,0,1,1,0,0);if(m_capwnd==NULL){////log.WriteString("nUnabletocreatecapturewindow");returnFALSE;}//connectcallbackfunctionscapSetUserData(m_capwnd,this);//Changedestroyfunctionsalso........capSetCallbackOnVideoStream(m_capwnd,OnCaptureVideo);capGetDriverDescription(index,devname,100,devversion,100);sprintf(str,"nDrivername=%sversion=%s",devname,devversion);//log.WriteString(str);//Connecttowebcamdriver-136- 长沙学院毕业设计if(!capDriverConnect(m_capwnd,index)){//Devicemaybeopenalreadyoritmaynothavebeen//closedproperlylasttime.AfxMessageBox("UnabletoopenVideoCaptureDevice");//log.WriteString("nUnabletoconnectdrivertothewindow");m_capwnd=NULL;returnFALSE;}//Setthecaptureparametersif(SetCapturePara(w,h)==FALSE){//log.WriteString("nSettingcaptureparametersfailed");capDriverDisconnect(m_capwnd);returnFALSE;}returnTRUE;}/***Startcapturingframesfromwebcam**/BOOLVideoCapture::StartCapture(){//Startlivecapturing...if(capCaptureSequenceNoFile(m_capwnd)==FALSE){//log.WriteString("nFailedtocaptureSequence..");returnFALSE;}returnTRUE;}-136- 长沙学院毕业设计/***Stopthecapturingprocess**/BOOLVideoCapture::StopCapture(){capCaptureStop(m_capwnd);capCaptureAbort(m_capwnd);Sleep(500);returnTRUE;}/***Stopthecatpureprocessanddisconnectthedriver**/voidVideoCapture::Destroy(){if(m_capwnd==NULL)return;//StopthecapturingprocesscapCaptureAbort(m_capwnd);//Disablethecallbackfunction..capSetCallbackOnVideoStream(m_capwnd,NULL);Sleep(300);//Thisdelayisimportant...//FinallydisconnectthedrivercapDriverDisconnect(m_capwnd);}-136- 长沙学院毕业设计/****Setvariouscaptureparameters...**/BOOLVideoCapture::SetCapturePara(intw,inth){CAPTUREPARMSCapParms={0};capCaptureGetSetup(m_capwnd,&CapParms,sizeof(CapParms));CapParms.fAbortLeftMouse=FALSE;CapParms.fAbortRightMouse=FALSE;CapParms.fYield=TRUE;CapParms.fCaptureAudio=FALSE;CapParms.wPercentDropForError=50;if(capCaptureSetSetup(m_capwnd,&CapParms,sizeof(CapParms))==FALSE){//log.WriteString("nFailedtosetthecaptureparameters");returnFALSE;}//SetVideoFormatcapGetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo));m_bmpinfo.bmiHeader.biWidth=w;m_bmpinfo.bmiHeader.biHeight=h;//lizhengaddfortype!nVideoType=m_bmpinfo.bmiHeader.biBitCount;BOOLret=capSetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo));-136- 长沙学院毕业设计if(ret==TRUE){//log.WriteString("nVideoparameterssetproperly");}else{returnFALSE;}returnTRUE;}/****AllocateMemoryforDIBimagebuffer**/intVideoCapture::AllocateMemory(PBITMAPINFO&bmpinfo){intsize1,size2,size;BITMAPINFOtbmp;charstr[200];capGetVideoFormat(m_capwnd,&tbmp,sizeof(tbmp));size1=getFormatSize(tbmp);size2=getImageSize(tbmp);size=size1+size2;sprintf(str,"nFormatsize=%dimagesize=%d,fun_size=%d",size1,size2,capGetVideoFormatSize(m_capwnd));//log.WriteString(str);bmpinfo=(BITMAPINFO*)newBYTE[size];if(bmpinfo==NULL){-136- 长沙学院毕业设计AfxMessageBox("Unabletoallocatememory");return-1;}memset(bmpinfo,0,sizeof(*bmpinfo));capGetVideoFormat(m_capwnd,bmpinfo,sizeof(*bmpinfo));returnsize1;}/****CalculatestheFormatSizeforDIBimage**/intVideoCapture::getFormatSize(BITMAPINFObmp){intsize;size=(bmp.bmiHeader.biSize!=0)?bmp.bmiHeader.biSize:sizeof(BITMAPINFOHEADER);//return(size+bmp.bmiHeader.biClrUsed*sizeof(RGBQUAD));returnsize;//RGBQUADisabsentfor24bitbmpimage.}/***CalculatestheSizeofImage**/intVideoCapture::getImageSize(BITMAPINFObmp){intsize;-136- 长沙学院毕业设计BITMAPINFOHEADERhead=bmp.bmiHeader;if(head.biSizeImage==0){size=(head.biWidth*head.biHeight*head.biBitCount)/8;}elsesize=head.biSizeImage;returnsize;}/***Invokedwhenthevideoframeiscapturedbythedriver***/LRESULTCALLBACKOnCaptureVideo(HWNDmwnd,LPVIDEOHDRlphdr){VideoCapture*vidcap=(VideoCapture*)capGetUserData(mwnd);if(vidcap!=NULL)((CCameraVideoDlg*)(vidcap->dlg))->SendVideo(lphdr->lpData,lphdr->dwBytesUsed);returnTRUE;}#ifndef_BMP2JPG_H_#define_BMP2JPG_H_#include#defineMaxHeight320classCDib{protected:-136- 长沙学院毕业设计structRGBData{unsignedcharBlue;unsignedcharGreen;unsignedcharRed;};RGBData*data[MaxHeight];//存储彩色图像的RGB三色typedefstruct{doublere;doubleim;}COMPLEX;//复数运算的结构体typedefstruct{intzero_num;intdigit;}C_RLE;//记录游程的长度和数据的结构体public:LONGwidth,height;//图像的宽度和高度C_RLERLE[64];//记录8*8的游程数据inttable[64];//记录8*8的数据块经量化和Z型扫描结果//intEncodeJpeg;//32位的数据缓冲区,用于把不等长的码串串成4个字节以便写入JPEG文件intsurplus;//32位数据缓冲区中剩余没使用的位长,使用数据缓冲区从高位到低位public:-136- 长沙学院毕业设计CDib();~CDib();BOOLLoad(unsignedchar*RGBBuff,intwidth,intheight);intSaveJpeg(byte*pOut);voidPre_DCT(double*sourcedata);BOOLDCT(double*x,intn,unsignedchar*QuantTable);intRLEProg();intnTlen;BOOLWriteHuffmanData(byte*pOut);BOOLHuffmanTable(unsignedchar*bit,unsignedchar*val);voidWrite32bit(byte*pOut);voidShiftWrite(intac_huffmanbitnum,intac_huffmancode,byte*pOut);BOOLWriteSurplus(byte*pOut);intWriteData(intpreDC,int*DChufco,int*DChufsi,int*AChufco,int*AChufsi,byte*pOut);};#endif#include#include"bmp2Jpg.h"#include#include-136- 长沙学院毕业设计#definePI(double)3.1415926535unsignedcharLumQuantTable[64]={//luminance标准亮度量化表///*16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99*//////////////////////第二种效果较好,但是还是有点模糊/////////////////////0x8,0x6,0x6,0x7,0x6,0x5,0x8,0x7,0x7,0x7,0x9,0x9,0x8,0xa,0xc,0x14,0xd,0xc,0xb,0xb,0xc,0x19,0x12,0x13,0xf,0x14,0x1d,0x1a,0x1f,0x1e,0x1d,0x1a,0x1c,0x1c,0x20,0x24,0x2e,0x27,0x20,0x22,0x2c,0x23,0x1c,0x1c,0x28,0x37,0x29,0x2c,0x30,0x31,0x34,0x34,0x34,0x1f,0x27,0x39,0x3d,0x38,0x32,0x3c,0x2e,0x33,0x34,0x32};unsignedcharChrQuantTable[64]={//chrominance标准色度量化表0x09,0x09,0x09,0x0c,0x0b,0x0c,0x18,0x0d,-136- 长沙学院毕业设计0x0d,0x18,0x32,0x21,0x1c,0x21,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,};unsignedcharLumDCHuffmanBit[17]={0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0};//亮度DC哈夫曼表的位值unsignedcharLumDCHuffmanVal[12]={0,1,2,3,4,5,6,7,8,9,10,11};//亮度DC哈夫曼表的码值unsignedcharLumACHuffmanBit[17]={0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d};//亮度AC哈夫曼表的位值unsignedcharLumACHuffmanVal[162]={//亮度AC哈夫曼表的码值0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,-136- 长沙学院毕业设计0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa};unsignedcharChrDCHuffmanBit[17]={0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};unsignedcharChrDCHuffmanVal[12]={0,1,2,3,4,5,6,7,8,9,10,11};unsignedcharChrACHuffmanBit[17]={0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};unsignedcharChrACHuffmanVal[162]={0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,-136- 长沙学院毕业设计0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa};staticconstshortzig[8*8]={//Z型扫描的顺序0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63};intehufco[251],ehufsi[251];CDib::CDib(){surplus=32;//EncodeJpeg=0;//height=0;width=0;nTlen=0;for(inti=0;i<64;i++)table[i]=0;-136- 长沙学院毕业设计for(i=0;iMaxHeight){return(FALSE);}LONGi,j;-136- 长沙学院毕业设计for(i=0;i=0;y--){memcpy(data[y],RGBBuff+startpos,width*3);//数组data存储24位色BMP文件的图像数据startpos=startpos+width*3+width%4;//*****此处很重要,位图行的字节数等于}//行除以4乘以3,再加上行除以4的余。24位图每象素3字节return(TRUE);}/////////////////////////////////////////////JPEG文件的存储///////////////////////////////////////////-136- 长沙学院毕业设计intCDib::SaveJpeg(byte*pOut){//time_ttBegin,tEnd;//time(&tBegin);if(pOut==NULL)return(0);unsignedshortintfilehead=0xd8ff;//JPEG标识符FFD8(16bit)unsignedcharapp0[18]={0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x00};unsignedcharquant0[5]={0xFF,0xDB,0x00,0x43,0x00};//量化表标记头的前几个字节,后接具体的量化表。unsignedcharquant1[5]={0xFF,0xDB,0x00,0x43,0x01};unsignedcharGreyFrame[13]={0xff,0xc0,0x00,0x0b,0x08,0,0,0,0,0x01,0x01,0x11,0x00};unsignedcharColorFrame[19]={0xff,0xc0,0x00,0x11,0x08,0,0,0,0,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,0x01};//真彩色帧开始的标识符unsignedcharLumDchuffman[5]={0xff,0xc4,0x00,0x1f,0x00};unsignedcharLumAchuffman[5]={0xff,0xc4,0x00,0xb5,0x10};unsignedcharChrDchuffman[5]={0xff,0xc4,0x00,0x1f,0x01};unsignedcharChrAchuffman[5]={0xff,0xc4,0x00,0xb5,0x11};unsignedcharColorSos[14]={0xff,0xda,0x00,0x0c,0x03,0x01,0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00};//扫描开始(SOS)标记符unsignedchareoi[2]={0xff,0xd9};//文件结束标识符EndofImage-136- 长沙学院毕业设计GreyFrame[5]=ColorFrame[5]=height/256;GreyFrame[6]=ColorFrame[6]=height%256;//图像的高度GreyFrame[7]=ColorFrame[7]=width/256;GreyFrame[8]=ColorFrame[8]=width%256;//图像的宽度///////////////////////////////////////////////////////////////////////////////////file.Write(&filehead,sizeof(unsignedshortint));//写JPEG标识符FFD8memcpy(pOut,&filehead,sizeof(unsignedshortint));nTlen+=sizeof(unsignedshortint);//file.Write(app0,18);//写app0memcpy(pOut+nTlen,app0,18);nTlen+=18;//file.Write(quant0,5);//写量化表标记头前5个字节memcpy(pOut+nTlen,quant0,5);nTlen+=5;//file.Write(LumQuantTable,64);//写量化表的64个字节memcpy(pOut+nTlen,LumQuantTable,64);nTlen+=64;//file.Write(quant1,5);memcpy(pOut+nTlen,quant1,5);nTlen+=5;//file.Write(ChrQuantTable,64);memcpy(pOut+nTlen,ChrQuantTable,64);nTlen+=64;-136- 长沙学院毕业设计//file.Write(ColorFrame,19);//写帧开始(SOF)的标识符memcpy(pOut+nTlen,ColorFrame,19);nTlen+=19;//file.Write(LumDchuffman,5);memcpy(pOut+nTlen,LumDchuffman,5);nTlen+=5;//file.Write(LumDCHuffmanBit+1,16);memcpy(pOut+nTlen,LumDCHuffmanBit+1,16);nTlen+=16;/*从DCHuffmanBit数组的第二位开始写*///file.Write(LumDCHuffmanVal,12);memcpy(pOut+nTlen,LumDCHuffmanVal,12);nTlen+=12;//file.Write(LumAchuffman,5);memcpy(pOut+nTlen,LumAchuffman,5);nTlen+=5;//file.Write(LumACHuffmanBit+1,16);memcpy(pOut+nTlen,LumACHuffmanBit+1,16);nTlen+=16;/*从ACHuffmanBit数组的第二位开始写*///file.Write(LumACHuffmanVal,162);memcpy(pOut+nTlen,LumACHuffmanVal,162);nTlen+=162;//file.Write(ChrDchuffman,5);memcpy(pOut+nTlen,ChrDchuffman,5);nTlen+=5;-136- 长沙学院毕业设计//file.Write(ChrDCHuffmanBit+1,16);memcpy(pOut+nTlen,ChrDCHuffmanBit+1,16);nTlen+=16;/*从DCHuffmanBit数组的第二位开始写*///file.Write(ChrDCHuffmanVal,12);memcpy(pOut+nTlen,ChrDCHuffmanVal,12);nTlen+=12;//file.Write(ChrAchuffman,5);memcpy(pOut+nTlen,ChrAchuffman,5);nTlen+=5;//file.Write(ChrACHuffmanBit+1,16);memcpy(pOut+nTlen,ChrACHuffmanBit+1,16);nTlen+=16;/*从ACHuffmanBit数组的第二位开始写*///file.Write(ChrACHuffmanVal,162);memcpy(pOut+nTlen,ChrACHuffmanVal,162);nTlen+=162;//file.Write(ColorSos,14);//写真彩色图像SOS标记符memcpy(pOut+nTlen,ColorSos,14);nTlen+=14;WriteHuffmanData(pOut);//开始向JPEG文件中写入数据WriteSurplus(pOut);//file.Write(eoi,2);//写JPEG文件结束标识符memcpy(pOut+nTlen,eoi,2);nTlen+=2;-136- 长沙学院毕业设计//time(&tEnd);//doublenCostTime=difftime(tEnd,tBegin);//CStringstrCostTime;//strCostTime.Format("JPEG编码完成!n共花%.0lf秒",nCostTime);//AfxMessageBox(strCostTime);//TRACE(strCostTime);return(nTlen);}/**************************************************************************函数名称:Pre_DCT()*参数:*double*sourcedata-指向时域值的指针*返回值:无*说明:该函数用来实现8*8快速离散余弦变换。************************************************************************/voidCDib::Pre_DCT(double*sourcedata){doubleconstC1=0.9808;doubleconstC2=0.9239;doubleconstC3=0.8315;doubleconstC4=0.7071;doubleconstC5=0.5556;doubleconstC6=0.3827;doubleconstC7=0.1951;doubleS18,S27,S36,S45,S1845,S2736;doubleD18,D27,D36,D45,D1845,D2736;double*data;-136- 长沙学院毕业设计inti;//后面有专门的地方使亮度值减去128//行DCT变换data=sourcedata;for(i=0;i<8;i++){S18=data[0]+data[7];S27=data[1]+data[6];S36=data[2]+data[5];S45=data[3]+data[4];S1845=S18+S45;S2736=S27+S36;D18=data[0]-data[7];D27=data[1]-data[6];D36=data[2]-data[5];D45=data[3]-data[4];D1845=S18-S45;D2736=S27-S36;data[0]=0.5*(C4*(S1845+S2736));data[1]=0.5*(C1*D18+C3*D27+C5*D36+C7*D45);data[2]=0.5*(C2*D1845+C6*D2736);data[3]=0.5*(C3*D18-C7*D27-C1*D36-C5*D45);data[4]=0.5*(C4*(S1845-S2736));data[5]=0.5*(C5*D18-C1*D27+C7*D36+C3*D45);data[6]=0.5*(C6*D1845-C2*D2736);data[7]=0.5*(C7*D18-C5*D27+C3*D36-C1*D45);data+=8;-136- 长沙学院毕业设计}///////////////////////////////////////////////////////列DCT变换data=sourcedata;for(i=0;i<8;i++){S18=data[0*8]+data[7*8];S27=data[1*8]+data[6*8];S36=data[2*8]+data[5*8];S45=data[3*8]+data[4*8];S1845=S18+S45;S2736=S27+S36;D18=data[0*8]-data[7*8];D27=data[1*8]-data[6*8];D36=data[2*8]-data[5*8];D45=data[3*8]-data[4*8];D1845=S18-S45;D2736=S27-S36;data[0*8]=0.5*(C4*(S1845+S2736));data[1*8]=0.5*(C1*D18+C3*D27+C5*D36+C7*D45);data[2*8]=0.5*(C2*D1845+C6*D2736);data[3*8]=0.5*(C3*D18-C7*D27-C1*D36-C5*D45);data[4*8]=0.5*(C4*(S1845-S2736));data[5*8]=0.5*(C5*D18-C1*D27+C7*D36+C3*D45);data[6*8]=0.5*(C6*D1845-C2*D2736);data[7*8]=0.5*(C7*D18-C5*D27+C3*D36-C1*D45);-136- 长沙学院毕业设计data++;}}///////////////////////////////////////////////////////////对8*8的图像块进行DCT变换,量化之后进行Z型扫描/////////////////////////////////////////////////////////BOOLCDib::DCT(double*x,intn,unsignedchar*QuantTable){double*Light=newdouble[64];inti;for(i=0;i=0)quant_val[i]=(int)(Light[i]/QuantTable[i]+0.5);elsequant_val[i]=(int)(Light[i]/QuantTable[i]-0.5);}-136- 长沙学院毕业设计//对量化矩阵进行Z型扫描for(i=0;i<64;i++)table[zig[i]]=quant_val[i];deleteLight;////////////////////////////////returnTRUE;}//////////////////////////////////////////////////////////游程编码子程序////////////////////////////////////////////////////////intCDib::RLEProg(){//C_RLERLE[64];///////初始化RLE编码数组///////////for(inti=0;i<64;i++){RLE[i].zero_num=0;RLE[i].digit=0;}///////开始RLE编码////////////////intj=0;//零的个数intk=0;//8*8的数据块的游程长度inttemp;//由temp判断EOB的位置for(i=1;i<64;i++)//去除Z型扫描之后的第一个元素,即DC的值{if(table[i]!=0)-136- 长沙学院毕业设计temp=i;//此循环判断从哪一个元素开始以后的元素全为零}for(i=1;i<=temp;i++){if(table[i]==0){if(j<16)j++;else{RLE[k].zero_num=j-1;//当连续零的个数为16时,存为(15,0)。此时j=16,因此要减去1RLE[k].digit=0;j=0;k++;}}else{RLE[k].zero_num=j;RLE[k].digit=table[i];j=0;k++;}}if(temp!=63)//当游程数为63时,不能写结束标识符EOB,即(0,0)。temp=63说明最后一位不是零,而是非零数。{RLE[k].zero_num=0;RLE[k].digit=0;//写RLE编码的结束标志EOB,即(0,0)k++;//k为RLE的总个数}returnk;//K为游程的长度}//////////////////////////////////////////////////////////////此函数可得到哈夫曼码表和码长-136- 长沙学院毕业设计//val为JPEG文件中存储的哈夫曼码表//bit为JPEG文件中存储的哈夫曼码表长度//由这两个参数可得到实际使用的不等长的哈夫曼码表//此处使用的是固定的哈夫曼码//////////////////////////////////////////////////////////////此处代码是参考的书上的程序流程图BOOLCDib::HuffmanTable(unsignedchar*bit,unsignedchar*val){intk=0,i=1,j=1;intlastk;charhuffsize[162];/////////////////////////////intcode=0,si,p;inthuffcode[162];///////////////////////////////intehufco[251],ehufsi[251];while(i<=16)//{while(j<=bit[i]){huffsize[k]=i;k=k+1;j=j+1;}i=i+1;j=1;}huffsize[k]=0;lastk=k;p=0;code=0;si=huffsize[0];while(huffsize[p]){while(((int)huffsize[p])==si){huffcode[p]=code;p++;code++;}code<<=1;-136- 长沙学院毕业设计si++;}for(p=0;p>1];//记得清除内存Cb[i]=newchar[width>>1];}for(i=0;i>1][i>>1]=0;Cb[j>>1][i>>1]=0;}for(j=0;j>1);j++)//height/2for(i=0;i<(width>>1);i++)//width/2{Cr[j][i]=(int)(-0.0813*data[j<<1][i<<1].Blue-0.4187*data[j<<1][i<<1].Green+0.5*data[j<<1][i<<1].Red);Cb[j][i]=(int)(0.5*data[j<<1][i<<1].Blue-0.3313*data[j<<1][i<<1].Green-0.1687*data[j<<1][i<<1].Red);}for(ii=0;ii<(r_height>>4);ii++)//r_height/16for(jj=0;jj<(r_width>>4);jj++)//r_width/16{/////////00///////////////////////for(i=0;i<8;i++)-136- 长沙学院毕业设计for(j=0;j<8;j++){xx[(i<<3)+j]=Y[(ii<<4)+i][(jj<<4)+j];}DCT(xx,64,LumQuantTable);LumPreDC=WriteData(LumPreDC,LumDChufco,LumDChufsi,LumAChufco,LumAChufsi,pOut);/////////01////////////////////////////for(i=0;i<8;i++)for(j=0;j<8;j++){xx[(i<<3)+j]=Y[(ii<<4)+i][(jj<<4)+8+j];}DCT(xx,64,LumQuantTable);LumPreDC=WriteData(LumPreDC,LumDChufco,LumDChufsi,LumAChufco,LumAChufsi,pOut);///////////10/////////////////////////////for(i=0;i<8;i++)for(j=0;j<8;j++){xx[(i<<3)+j]=Y[(ii<<4)+8+i][(jj<<4)+j];}DCT(xx,64,LumQuantTable);LumPreDC=WriteData(LumPreDC,LumDChufco,LumDChufsi,LumAChufco,LumAChufsi,pOut);/////////11/////////////////////////////for(i=0;i<8;i++)for(j=0;j<8;j++){xx[(i<<3)+j]=Y[(ii<<4)+8+i][(jj<<4)+8+j];}DCT(xx,64,LumQuantTable);LumPreDC=WriteData(LumPreDC,LumDChufco,LumDChufsi,LumAChufco,LumAChufsi,pOut);//////////////////////先蓝色后红色///////////////////////////////////////for(i=0;i<8;i++)for(j=0;j<8;j++)-136- 长沙学院毕业设计{xx[(i<<3)+j]=Cb[(ii<<3)+i][(jj<<3)+j];//蓝色色差}DCT(xx,64,ChrQuantTable);CbPreDC=WriteData(CbPreDC,ChrDChufco,ChrDChufsi,ChrAChufco,ChrAChufsi,pOut);for(i=0;i<8;i++)for(j=0;j<8;j++){xx[(i<<3)+j]=Cr[(ii<<3)+i][(jj<<3)+j];//红色色差}DCT(xx,64,ChrQuantTable);CrPreDC=WriteData(CrPreDC,ChrDChufco,ChrDChufsi,ChrAChufco,ChrAChufsi,pOut);}for(i=0;i=pow(2,i))//计算nowDC的二进制位数(即分组值),i即为它的位数power_dc=i+1;}}else{power_dc=0;//DC值为零时分组为零}if(nowDC>0)//对直流分量编码{dc_huffmancode=DChufco[power_dc];dc_huffmanbitnum=DChufsi[power_dc];ShiftWrite(dc_huffmanbitnum,dc_huffmancode,pOut);ShiftWrite(power_dc,nowDC,pOut);}elseif(nowDC<0)//-136- 长沙学院毕业设计{dc_huffmancode=DChufco[power_dc];dc_huffmanbitnum=DChufsi[power_dc];ShiftWrite(dc_huffmanbitnum,dc_huffmancode,pOut);//abs1=((int)pow(2,power_dc)-1)-abs(nowDC);//DC为负,求绝对值后取其反码ShiftWrite(power_dc,abs1,pOut);//由DC值的位长和码串决定如何移入数据缓冲区并写入文件}else{ShiftWrite(2,0,pOut);//当nowDC=0时,其huffman码串为00,两位长,移入数据缓冲区}///////////////////////////////////////////////////////对AC分量进行编码//////////////////////////////////////////////////////////RLE_length=RLEProg();//游程编码,返回值为游程的个数intdigitTemp;for(i=0;i=pow(2,j))//pow(2,j)为求2的J次幂,此处判断digit是哪一组的数power_num=j+1;//最小为1,即最小分组为1}}else//当digit=0,分组为0{-136- 长沙学院毕业设计power_num=0;}/////////....................................if(digit<0){digitcode=(int)(pow(2,power_num)-1)-abs(digit);//有效位取反码,使有效位以外的位为0}else{digitcode=digit;}//**//////////////////////////////////////////////////huffmanval=(zero_num<<4)|power_num;//使零的个数与该游程值所在的分组合为一个字节,以便用哈夫曼码表ac_huffmancode=AChufco[huffmanval];//得到哈夫曼码表ac_huffmanbitnum=AChufsi[huffmanval];//得到哈夫曼码表的位长度ShiftWrite(ac_huffmanbitnum,ac_huffmancode,pOut);if(digit!=0||zero_num!=0)//当是EOI(EndofImage)时,不写数字位的0,否则要写数字位的0{ShiftWrite(power_num,digitcode,pOut);//游程不为(0,0)时,写入数据}}returnpreDC;}////////////////写最后数据缓冲区中已移到高位的码串,使其凑成整字节,不足字节位时后加1////////////BOOLCDib::WriteSurplus(byte*pOut){unsignedcharspare[4];EncodeJpeg=EncodeJpeg|((int)pow(2,surplus)-1);//使数据缓冲区中有效位以外的所有位为1if(surplus<32&&surplus>=24)//剩余位大于等于24,只写一个字节到JPEG文件{spare[0]=(EncodeJpeg&0xff000000)>>24;//file.Write(spare,1);memcpy(pOut+nTlen,spare,1);-136- 长沙学院毕业设计nTlen+=1;}elseif(surplus<24&&surplus>=16)//剩余位大于等于16而小于24,写2个字节{spare[0]=(EncodeJpeg&0xff000000)>>24;spare[1]=(EncodeJpeg&0xff0000)>>16;//file.Write(spare,2);memcpy(pOut+nTlen,spare,2);nTlen+=2;}elseif(surplus<16&&surplus>=8)//剩余位大于等于8而小于16,写3个字节{spare[0]=(EncodeJpeg&0xff000000)>>24;spare[1]=(EncodeJpeg&0xff0000)>>16;spare[2]=(EncodeJpeg&0xff00)>>8;//file.Write(spare,3);memcpy(pOut+nTlen,spare,3);nTlen+=3;}else//剩余位小于8,写4个字节{spare[0]=(EncodeJpeg&0xff000000)>>24;spare[1]=(EncodeJpeg&0xff0000)>>16;spare[2]=(EncodeJpeg&0xff00)>>8;spare[3]=EncodeJpeg&0xff;//file.Write(spare,4);memcpy(pOut+nTlen,spare,4);nTlen+=4;}EncodeJpeg=surplus=0;////////////////////////////////////////////////////returnTRUE;}////////////////////////////////////////////////////////把一个四字节的数由高字节到低字节的顺序写入文件//////////////////////////////////////////////////////voidCDib::Write32bit(byte*pOut)-136- 长沙学院毕业设计{unsignedcharbuf[4],insert=0x00;inti;buf[0]=(EncodeJpeg&0xff000000)>>24;//把32位的JPEG编码整数由高位到低位存入buf数组中buf[1]=(EncodeJpeg&0xff0000)>>16;//以便由高位到低位写入JPEG文件中,因直接写入,buf[2]=(EncodeJpeg&0xff00)>>8;//将由低位到高位写入文件。buf[3]=EncodeJpeg&0xff;for(i=0;i<4;i++)//EncodeJpeg的32位已满,写入文件{//file.Write(buf+i,1);memcpy(pOut+nTlen,buf+i,1);nTlen+=1;if(buf[i]==0xff)//如果某一字节为0xFF,则需插入一个数0x00//file.Write(&insert,1);//已定义insert为0x00{memcpy(pOut+nTlen,&insert,1);nTlen+=1;}}}///////////////////////////////////////////////////////////////////////////////////////////////////////voidCDib::ShiftWrite(inthuffmanbitnum,inthuffmancode,byte*pOut){inti,j,k;if(huffmanbitnum>i);Write32bit(pOut);//32位数据缓冲区填满后写入JPEG文件EncodeJpeg=0;//数据缓冲区清零k=(int)pow(2,i)-1;//EncodeJpeg=(huffmancode&k)<<(32-i);//使被截断后剩余的码串移到32位数据缓冲区的高位surplus=32-i;//目前数据缓冲区剩余的位数}}-136- 长沙学院毕业设计致谢2012年12月份,我开始了毕业设计准备工作,时至今日,毕业设计已处在完善阶段。从一开始的迷茫、无从下手,紧接着进入状态、思路渐渐清晰,整个过程无法用语言来表达。经过几个月的辛勤耕耘,自己终于有了少许的收获,再回想这段时间为毕业设计而奋斗的日子,充满了回忆与感触。本次毕业设计,能够顺利的完成任务,与刘欣老师的耐心指导是分不开的。刘欣老师在毕业设计过程前期对于毕业设计的基本思路以及内容给予了我很大的引导,在技术方面更给了我全面详细的指导。设计后期,刘欣老师更是督促、指引我的论文写作。刘欣老师认真负责的教学态度,严谨的治学精神和深厚的理论水平都使我受益匪浅。他勤奋严谨的为人也给我留下了极为深刻的印象。从刘欣老师身上我学到了很多东西。无论是在理论上或者实践中,都使我得到不少的提高,这对于我以后的学习以及工作都是一种巨大的帮助。在此,特向刘欣老师表示衷心的感谢。另外我还要感谢杨凤年老师以及答辩组所有老师在开题答辩初期对我毕业设计思路做出的部分指引。感谢广州网视通信息科技有限公司给我毕业设计期间的实习学习机会。以及公司的罗冬林经理,感谢罗冬林经理在工作上对我的教育与帮助,让我学习到实际项目中的许多经验并将其应用到毕业设计中,这个过程使我有所思、有所学、有所悟。最后,再一次向所有引导、帮助过我的人致以诚挚的谢意,祝愿你们工作顺心、万事胜意!学生签名:日期:-136-'