分享

第10章 图象处理编程工具及简单的多媒体编程

 学海无涯GL 2013-09-29

10  图象处理编程工具及简单的多媒体编程

在前九章,我们主要是介绍一些数字图象处理的基本原理和算法,很多细节和优化的算法都没有提,所以程序的通用性和效率并不理想。其实有很多优秀的图象处理编程工具,功能强大,速度很快。在实际的编程中,可以调用它们提供的功能来满足我们自己的需求,提高了编程效率和代码的正确性。

在这一章里,将介绍图象处理编程工具LeadTools(OCX)。给出的例程中要用到Visual C++(以下简称VC)AppWizardMFC的一些特性,不熟悉C++的读者可以先看看相关的参考书。

10.1 LeadTools

LeadTools(OCX)Lead Technologies公司出品的一款功能强大的图象处理编程工具,目前的最新版本是Lead8.0(1997.7.25)LeadTools实质上是一个OCX控件。先来说说什么是OCX控件?

如果你用过Visual Basic或者Delphi一类的可视化编程工具,那么对控件这个概念一定不会陌生,就是那些工具条上的小按钮,如EditBoxGridImageBoxTimer等等。每个控件都有自己的事件(事件) 、方法(方法)和属性(属性)。使用了控件的编程非常容易。首先,在程序的设计阶段可以设置一些属性,如大小,位置,标题(caption)等等;在程序运行阶段,可以更改这些属性,还可以针对不同的事件,调用不同的方法来实现对该控件的控制。控件就好象一块块的积木,程序要做的事只是将这些积木搭起来。控件的最大好处是可以重复使用,甚至可以在不同的编程语言之间使用,例如你可以在VB中嵌入用VC开发的控件。

控件的本质是微软公司的对象链接和嵌入(OLE)标准。由于它充分利用了面向对象的优点,使得程序效率得到了很大的提高,从而得到了广泛的应用。国外有很多公司就是专门制作各种各样控件的。控件的最早形式是以.VBX的格式出现的,后来变成了.OCX。由于Internet的广泛流行,微软公司推出了ActiveX技术,就是从OLE发展起来的,加入了WWW上的功能。所以目前最流行的是ActiveX控件。

介绍完了OCX控件的概念,下面我们以Lead Version5.1为例,来看看LeadTools究竟有哪些功能?Lead Version5.1可以在正版MicroSoft Visual C++4.1安装光盘中Msdev\samples\ocx\leadtoolsMsdev\redist\redist下找到,主要是4个文件, Lead51n.dllLead32.ocxLead.licLtocx.hlp。如果你想了解LeadTools的最新信息,可以访问以下www网址:http://www./

LeadTools主要有以下几大功能:

(1) 对显示设备的全面支持:在显示时,你的程序中无需考虑是哪种显示模式,如16色还是真彩色。LeadTools为你做了所有的事。当然你也可以通过设置参数获得对显示设备更多的控制。你还可以实现自己的调色板。

(2) 支持多种文件格式:表10.1LeadTools所支持的常用文件格式,其中读表示用LeadTools能打开的文件格式,写表示LeatTools能存成的文件格式:

10.1  LeadTools支持的常用文件格式

文件格式

(/象素)

(/象素)

JFIF:一种常用的Jpeg文件格式,LeadTools支持YUV 4:4:4, 4:2:2, 4:1:1(彩色)YUV 4:0:0(灰度)

8 (灰度)

24(彩色)

8 (灰度)

24(彩色)

JFIF:另一种常用的Jpeg文件格式,LeadTools支持YUV 4:4:4, 4:2:2, 4:1:1(彩色)YUV 4:0:0(灰度)

8 (灰度)

24(彩色)

8 (灰度)

24(彩色)

TIFFTiff文件有很多种,LeadTools支持常用的几种

148162432,还包括另一种颜色表示方法CMYK (LZW压缩) RLE (LZW压缩)

1, 4, 8, 16, 24

MPT:一种多页(MultiPage)Tiff文件格式,类似于动画Gif

148162432,还包括另一种颜色表示方法CMYK (LZW压缩) RLE (LZW压缩)

1, 4, 8, 16, 24

TIFF LZW:采用LZW压缩的Tiff格式,使用时要获得Unisys公司的认可。

1, 4, 8, 16, 24, 32

1, 8, 16, 24

TIFF CCITT Group 3:是一种用于二值黑白图(如传真)Tiff压缩格式。

1

1

TIFF CCITT Group 4:是一种用于二值黑白图(如传真)Tiff压缩格式。比Group 3有更高的压缩比。

1

1

TGA (TARGA)Truevision公司的一种文件格式,LeadTools支持所有未压缩的,及用RLE算法压缩的TGA文件。

8, 16, 24, 32

8, 16, 24, 32

GIF:由CompuServe公司定义的一种文件格式,是html语言采用的一种文件格式。要注意的是,使用采用了LZW压缩的Gif文件时,首先要获得Unisys公司的认可。

1, 4, 8

8

Photoshop 3.0 (PSD)Adobe公司PhotoShop3.0所采用的文件格式。

1, 8, 24

1, 8, 24

Windows Bitmap (BMP):由微软公司定义的文件格式。

1, 4, 8, 24(未压缩)

1, 4, 8(采用RLE压缩)

1, 4, 8, 24

Windows Metafile (WMF):一种矢量图文件格式。在Word中用到。

8, 24

8, 24

PCX:由Zsoft公司制定的一种文件格式,采用了行程编码。

1, 4, 8, 24

1, 4, 8, 24

SUN Raster (RAS):在Sun UNIX平台上的一种文件格式。

1, 4, 8, 24, 32

1, 4, 8, 24, 32

PCD:柯达公司的PhotoCD 文件格式。要注意的是要有PCDLIB32.DLL这个文件。

所有

不能写

以上只是常用的文件格式,除此以外还有很多其它的文件格式,感兴趣的读者可以参考帮助。

(3) 图象处理:如二值化、平滑、加噪声、增加对比度、色调、饱和度、亮度、Gamma校正、中值滤波、半影调、抖动、橡皮筋、滚动、填充、反色、镜象、马赛克、浮雕、打印、扫描、拷贝、粘贴、裁剪、缩放、截屏、调色板、直方图、有关数据库的操作、还有制作幻灯的功能,如淡入、淡出、卷帘等等、真的很爽。表10.2Version5.1的所有属性、事件、和方法列表,看看有没有你所需要的功能。以字母顺序排列,其中标[P]的表示只有专业级(Professional)和特殊级(Express)用户才能使用。

10.2  LeadTools的事件、属性、方法

AboutBox 方法:显示LeadTools的“关于”信息

[P] AddNoise 方法:增加随机噪声

AutoRepaint 属性:该属性为真时,位图自动重画

AutoScroll 属性:该属性为真时,当位图超出窗口范围时,自动出现滚动条

AutoSetRects 属性:该属性为真时,自动调整窗口大小

[P] Average 方法:平滑

BackColor 属性:该属性设置位图的背景色

BackErase 属性:该属性为真时,擦除控件的背景

[E] BinaryFilter 方法:对黑色对象进行腐蚀或膨胀操作

Bitmap 属性:该属性为位图句柄

BitmapBits 属性:该属性为每个象素所占的比特数

BitmapHeight 属性:该属性为位图的高

BitmapPalette 属性:该属性设置调色板中某一项的RGB

BitmapWidth 属性:该属性为位图的宽

BitmapXRes 属性:该属性为位图的水平分辨率

BitmapYRes 属性:该属性为位图的垂直分辨率

[E] BitonalScaling 属性:设置该属性,以增强二值图的显示效果

BorderStyle 属性:该属性为0时,控件周围没有边框,为1时有边框

[P] Capture 方法:从某一设备上下文指定的矩形区域中获得位图(截屏)

Click 事件:当用户点击控件时,触发该事件

[P] ColorMerge 方法:融合调色板

[P] ColorPlanes 属性:该属性为灰度图的调色板数组

ColorRes 方法:颜色数转换

[P] ColorSeparate 方法:按照调色板将位图分离成一个个的灰度图

[P] Combine 方法:将两幅图结合,例如另一幅图是一个边沿检测的滤波器

Contrast 方法:增加或减少位图的对比度

Copy 方法:将位图拷贝至剪贴板

CreateBitmap 方法:对位图初始化并分配内存,但不调入任何数据

[P] dbAddNew 方法:为当前记录集增加一个新的空记录

[P] dbCanAppend 属性:该属性为真时,表示可以在当前记录集中增加一个记录

[P] dbCanRestart 属性:该属性为真时,表示可以从数据库中重建记录集

[P] dbCanScroll 属性:该属性为真时,表示数据源支持dbMove方法,可以在记录集中滚                     

[P] dbCanUpdate 属性:该属性为真时,表示可以在当前记录集中增加或者更新一个记录

[P] dbClose 方法:关闭当前记录集和数据库

[P] dbCurrentRecord 属性:记录集中当前记录号

[P] dbDelete 方法:删除当前记录

[P] dbEdit 方法:为更新当前记录做准备

[P] dbEditMode 属性:指示当前记录的编辑模式,如只读,可编辑,可添加

[P] dbIsBOF 属性:指示是否到了最前面的记录

[P] dbIsDeleted 属性:指示当前记录是否已经被删除

[P] dbIsEOF 属性:指示是否到了最后面的记录

[P] dbIsOpen 属性:指示是否和一个数据库相连

DblClick 事件:当用户双击控件时,触发该事件

[P] dbLoadBits 属性:指示从数据库中调入位图时,每个象素所占的比特数,为0时,和原来位图的颜色数保持一致

[P] dbLockingMode 属性:当对数据库中已有记录进行更新时,该属性用来指定记录锁定模式

[P] dbMove 方法:将当前记录移动到指定位置

[P] dbMoveFirst 方法:选定记录集中的第一个记录

[P] dbMoveLast 方法:选定记录集中的最后一个记录

[P] dbMoveNext 方法:选定记录集中的下一个记录

[P] dbMovePrev 方法:选定记录集中的前一个记录

[P] dbOpen 方法:在ODBC类型的数据库中打开一个记录集

[P] dbRecordCount 属性:指示记录集中的记录数

[P] dbRequery 方法:从数据库中重建记录集

[P] dbUpdate 方法:更新数据库(当调用dbAddNew或者dbEdit)

[E] Deskew 方法:旋转位图使其变正,常用于扫描图象的自动纠斜

[E] Despeckle 方法:去除位图中的小斑点

DstClipHeight 属性:指定目标剪切矩形的高度

DstClipLeft 属性:指定目标剪切矩形的左坐标

DstClipTop 属性:指定目标剪切矩形的上坐标

DstClipWidth 属性:指定目标剪切矩形的宽度

DstHeight 属性:指定目标矩形的高度

DstLeft 属性:指定目标矩形的左坐标

DstTop 属性:指定目标矩形的上坐标

DstWidth 属性:指定目标矩形的宽度

[P] Emboss 方法:制作浮雕效果

Enabled 属性:指定控件是否使能

EnableMethodErrors 属性:指示控件是否导致了系统错误

[P] EnableProgressEvent 属性:指示控件是否产生一个进度状态的事件,用来指示已经完成的百分比

[P] EnableTwainEvent 属性:为真时,表示支持多页扫描,每扫一页产生一个TwainPage事件

Fill 方法:用指定颜色填充位图

Flip 方法:上下反转位图

ForceRepaint 方法:重画位图

ForePalette 属性:当为真时,将使用控件的调色板作为前景调色板

[P] GammaCorrect 方法:Gamma校正

GetBitmapDC 方法:获得位图的设备上下文

GetClientDC 方法:获得控件客户区的设备上下文

[P] GetDDB 方法:从控件位图中获得设备相关位图

[P] GetDIB 方法:从控件位图中获得设备无关位图

GetFileInfo 方法:获得指定文件的信息

[P] GetHistogram 方法:获得颜色直方图

GetPalette 方法:获得调色板

[P] GetPicture 方法:返回一个Picture的对象,是位图的一个拷贝

Grayscale 方法:将彩色图转成256级灰度图

Halftone 方法:半影调效果

[P] HistoContrast 方法:使用直方图指定中间亮度,用以增加图象的对比度

[P] HistoEqualize 方法:直方图均衡化

[P] HistogramTable 属性:得到指定强度级别的颜色出现的次数

[P] Hue 方法:改变图象色调

hWnd 属性:得到控件的窗口句柄

InfoBits 属性:得到指定图象文件每个象素所占的比特数

InfoCompress 属性:得到指定图象文件所用的压缩方法

InfoFormat 属性:得到指定图象文件的格式

InfoHeight 属性:得到指定图象文件的高度

InfoPage 属性:对于多页图象文件,指示出该页的页号

[P] InfoPCDRes 属性:用来指示PhotoCD文件格式的分辨率

InfoSizeDisk 属性:得到文件大小

InfoSizeMem 属性:得到要调入该文件,其位图所占的内存大小

InfoWidth 属性:得到指定图象文件的宽度

Intensity 方法:改变图象的亮度

[P] IntensityDetect 方法:用来检测指定范围内的颜色

Invert 方法:反色,制作底片效果

KeyDown 事件:当用户按下键盘时,触发该事件

KeyPress 事件:当用户按下并抬起键盘时,触发该事件

KeyUp 事件:当用户抬起键盘时,触发该事件

Load 方法:调入一个图象文件到位图中

[P] LoadStamp 方法:在JFIF或者LEAD CMP压缩文件中调入一幅Thumbnail图象

[P] Median 方法:中值滤波

[P] Mosaic 方法:马赛克效果

MouseDown 事件:当鼠标按钮按下时,触发该事件

MouseIcon 属性:用户定制的鼠标光标形状

MouseMove 事件:当鼠标移动时,触发该事件

MousePointer 属性:已有的鼠标光标形状(如沙漏,箭头等等)

MouseUp 事件:当鼠标按钮抬起时,触发该事件

Paint 事件:控件的某一部分需要重画时,触发该事件

PaintDither 属性:指定抖动方法,是顺序的还是误差传递的

[P] PaintEffect 属性:指定显示效果,如卷帘,淡入,淡出

PaintPalette 属性:当用只能显示256色或更低的设备显示高颜色数位图时,用来指定调色板的模式,是用固定的调色板,还是用最佳调色板

[P] PaintWhileLoad 属性:当为真时,调入图象的同时就在屏幕上显示,当为假时,全部调入后才在屏幕上显示

Paste 方法:将图象数据从剪切板粘贴到指定的位图

[P] PCDRes 属性:指定PCD文件的分辨率

[P] Posterize 方法:增加海报效果,即将颜色数重新量化成较少的级别

PrintEnd 方法:结束打印工作

PrintStart 方法:开始打印工作

[P] ProgressStatus 事件:进度事件,用来得到已经完成的百分比

ReleaseBitmapDC 方法:释放位图设备上下文

ReleaseClientDC 方法:释放客户区设备上下文

[P] RemapIntensity 方法:使用一个查找表来改变位图的颜色值

[P] RemapTable 属性:RemapIntensity方法中用到的查找表

Render 方法:在任何设备上下文中打印或者显示图象

Resize 事件:当控件第一次显示或者大小改变时触发该事件

Reverse 方法:水平反转位图

Rotate 方法:旋转位图

RubberBandHeight 属性:橡皮筋的高度

RubberBandLeft 属性:橡皮筋的左坐标

RubberBandTop 属性:橡皮筋的上坐标

RubberBandVisible 属性:为真时,橡皮筋可见

RubberBandWidth 属性:橡皮筋的宽度

[P] Saturation 方法:改变图象的饱和度

Save 方法:将图象存成文件

[P] SaveWithStamp 方法:将位图存成包括一幅Thumbnail图象的JPEG或者LEAD CMP文件

ScaleHeight 属性:控件客户区高度

ScaleLeft 属性:控件客户区左坐标

ScaleMode 属性:控件的丈量单位,如厘米,象素,英寸等等

ScaleTop 属性:控件客户区上坐标

ScaleWidth 属性:控件客户区宽度

Scroll 事件:当滚动时,触发该事件

[P] SetDDB 方法:将一设备相关位图拷贝,并将该拷贝指派到控件上

[P] SetDIB 方法:将一设备无关位图拷贝,并将该拷贝指派到控件上

SetDstClipRect 方法:指定目标剪切矩形

SetDstRect 方法:指定目标矩形

[P] SetPicture 方法:将一Picture对象拷贝,并将该拷贝指派到控件上

SetRubberBandRect 方法:指定橡皮筋矩形

SetSrcClipRect 方法:指定源剪切矩形

SetSrcRect 方法:指定源矩形

[P] Sharpen 方法:锐化

[P] Shear 方法:错切

Size 方法:放缩

[P] SpatialFilter 方法:用指定的滤波器处理,如LAPLACESOBELEMBOSS等等

SrcClipHeight 属性:指定源剪切矩形的高度

SrcClipLeft 属性:指定源剪切矩形的左坐标

SrcClipTop 属性:指定源剪切矩形的上坐标

SrcClipWidth 属性:指定源剪切矩形的宽度

SrcHeight 属性:指定源矩形的高度

SrcLeft 属性:指定源矩形的左坐标

SrcTop 属性:指定源矩形的上坐标

SrcWidth 属性:指定源矩形的宽度

[P] StretchIntensity 方法:对比度扩展

Trim 方法:在指定的矩形区域内剪切图象

TwainAcquire 方法:扫描(Twain标准)

[P] TwainPage 事件:当进行多页扫描时,每扫完一页触发该事件(Twain标准)

TwainSelect 方法:选择扫描仪(Twain标准)

[P] Underlay 方法:将两幅结合起来,使得一幅图做另一幅图的文理

UserPalette 属性:指定调色板中的某一项颜色

VersionDate 属性:版本日期

VersionLevel 属性:版本级别(EXPRESS 或者PROFESSIONAL)

VersionMajor 属性:主版本号

VersionMinor 属性:副版本号

VersionProduct 属性:当前版本的全名

VersionTime 属性:版本时间

(4) 源代码例子:LeadTools的帮助做的特别好,这一点非常吸引人。每一个事件、方法、属性都有很详细的说明,后面都附有一个详细的例子。而且例子有很多种版本,如VC版、VB版、Delphi版、Access版,这样使用不同编程语言的程序员都能从中获得直接的帮助。

好了,介绍了这么多LeadTools的功能,下面我们给出一个最简单的利用LeadTools例子,其功能是显示任意一幅图(当然是Lead能支持的文件格式),图被缩放成和控件一样大小。

[例子10.1] Lead显示一幅图

步骤1:打开VC++5.0,用MFC AppWizard (exe)新建一个Project,起名为TestLead。要注意的是在Step1中,选定"Dialog based"Step2中,选定"ActiveX Controls",其它过程全部采用缺省值。

步骤2:把Lead控件添加到工具条中,方法是:(1)打开Project->Add To Project->Components and Controls菜单(其它的VC版本,如4.04.14.2,为Insert->Component…菜单),出现对话框,选择“Registered ActiveX Controls”那个目录(其它的VC版本为”OLE Controls”那一页)(2)选中"Lead Std Control"那一项,如图10.1所示。然后按下Insert菜单即可;

10.1  Lead控件

10.2

工具条

(3)如果没有该项,找到lead32.ocx文件所在的目录(一般为95的系统目录),选择该文件,按下Insert按钮即可(其它VC版本的操作方法是:按下Customize菜单,出现一个新的对话框,按下Import菜单,找到lead32.ocx文件所在的目录,选择该文件,按下Import按钮,再按下OK按钮,然后做(2)所做的工作即可)。按下Close按钮,关闭Component对话框。插入该控件后,会出现一个对话框,提示你新增加了两个类:CleadCpicture,选择Ok。打开对话框资源,选择IDIDD_TESTLEAD_DIALOG的对话框,这时可以看到该控件已经添加到工具条中,如图10.2所示。

步骤3:将Lead控件从工具条拖到对话框中,设置好合适的大小,右击该控件,选择Property菜单,设置其ID属性为IDC_LEAD1,删除“TODO: Place form controls on this dialog”的静态文本。

步骤4:按Ctrl+w,出现ClassWizard对话框,选择Member Variables那一页,为该ID添加一个变量m_Lead1CategoryControlVariable TypeClead

步骤5:编辑TestLeadDlg.cpp文件中的OnInitDialog()函数,在     // TODO: Add extra initialization here后加入如下的代码:

m_Lead1.Load(“c:\\test.jpg”,0,0);

m_Lead1.SetAutoScroll(TRUE);

m_Lead1.SetDstRect(0,0,m_Lead1.GetScaleWidth(), m_Lead1.GetScaleHeight());

m_Lead1.SetDstClipRect(0,0,m_Lead1.GetScaleWidth(), m_Lead1.GetScaleHeight());

m_Lead1.SetAutoRepaint(FALSE);

m_Lead1.ForceRepaint();

步骤6:编译运行,结果如图10.3所示。

10.3  10.1的运行结果

可以看到,使用了控件的编程是多么的简单。更复杂的应用,读者可以参考帮助来完成,要注意的是,使用了LeadTools的应用程序一定要注意版权问题,另外,程序中如果用到了LeatToolsOCX,在制作安装程序(如用InstallShield)时一定要将OLE的信息进行注册,否则用户无法正常运行程序。

10.2 DirectDraw

本节内容主要参考自微软公司的技术文档。

相信游戏玩家对DirectX这个词并不陌生。最近有越来越多的游戏用到了DirectX。那么DirectX究竟是什么呢?

Windows3.x的时代,由于Microsoft提供的Windows API不能对硬件直接操作,使得Windows3.x下的游戏不仅效果差,而且运行速度极慢。而DOS4GW有很多很好的性能,例如:可对硬件直接操作;访问超过16比特大小的内存区;可对保护模式编程等等,使得大部分游戏是在DOS4GW下利用如WATCOMC一类的开发工具编制的,如老版本的《仙剑奇侠传》。为了吸引游戏商到Windows平台上来,Microsoft专门开发了Windows的游戏接口WinG,然而效果并不理想。在推出Windows95之后,Microsoft又开发了该平台的GAME SDK,这就是DirectX

DirectX是非常成功的,很多优秀的游戏都又从DOS平台移植到Windows95平台,《仙剑奇侠传》出了Win95版本,Red Alert, Diablo,以及最近十分流行的Age of Empire,都用到了DirectX

DirectX技术的最大特点是能直接对硬件抽象层(HAL)操作,实现视频、声音的输出、网络相互通信,特别能对游戏杆直接编程。与传统的GDIMCI相比,不仅大大加快了速度,而且大大地提高了游戏的质量,有人甚至已将DirectX称为Windows95GAME OS。目前的最新版DirectX5.0 SDK包括DirectDrawDirectSoundDirectPlayDirect3DDirectInputDirectSetup六个部分。其中DirectDraw管理游戏的视频输出,DirectSound管理游戏的声音输出,DirectPlay管理游戏的网络通信,Direct3D管理游戏的三维图形,DirectInput管理游戏的游戏杆控制,DirectSetup管理游戏的安装。

因为本书的题目是图象处理编程,我们这里只介绍DirectDraw的大致原理。有的读者可能会说:“跑题了,图象处理编程和编游戏有什么关系?”其实DirectDraw并不只是用在游戏中,由于它的显示处理速度快,在很多和视频有关的软件中(比如说Mpeg的解码器)都可以用到。

DirectDraw是为速度而设计的,它绕过与Windows的图形设备相连的多个层次,直接与硬件的底层打交道。这很适合游戏编程,因为它着重于快速产生平稳的图形。

DirectDraw最重要的一点在于它对不同的显示适配器具有一个共同的接口。你不必管你的程序它是否会工作。DirectDraw利用包含在硬件抽象层(HAL)中的信息来决定显示适配器的功能。(HAL是由显示适配器厂商提供的)HAL为不同的硬件厂商和使用.DirectDraw的开发者提供了共同的接口。

然而,DirectDraw并不只限于利用显示适配器的硬件功能。如果你的程序指定了某一种特定的显示适配器,例如XXXX hardware blitter,但用户并没有该硬件,程序就会使用DirectDraw的硬件仿真层(HEL)。在这种情况下,DirectDraw利用内建的硬件仿真来仿真缺少的硬件。

下图一说明了DirectDraw和其他Windows显示构件的联系。

10.4  DirectDraw和其他Windows显示构件

DirectDraw APIDirectDraw对象组成,它表示具体的显示适配器。另外,DirectDraw API还包括表示surfaceDirectDrawSurface对象,表示surface调色板的DirectDrawPalette对象和表示剪接列表的DirectDrawClipper对象。可以用DirectDraw对象来创建DirectDrawSurfaceDirectDrawPalette对象。

本节只介绍到这里,目的主要是想说明由于游戏对显示速度的要求非常高,所以DirectDraw是为速度而设计的。如果要编写一个对速度要求很高(Mpeg的解码器)的图象处理系统中,可以考虑使用DirectDraw

10.3 简单的多媒体编程

前面讲过的内容都是针对数字图象处理这一领域的,现在来谈一些题外的东西,比如说多媒体和MPEG

多媒体这几个字,近年来是非常流行的。它包含的东西也是非常多的,除了文本,静态图象,还包括音频,视频等媒体信息。有时候在程序中加入一小段多媒体的东西,能给你的软件增色不少。

其实编制一个多媒体播放程序非常简单,关键代码不超过10行代码,你相信吗?其实质是MCIMCIMedia Control Interface(媒体控制接口)的缩写,它提供了一套与设备无关的命令消息和命令字来控制媒体的播放。MCI可以播放的文件类型有AVIWAVMIDIMPEG(如果系统中已经安装了MPEG的驱动程序,如安装XINGACTIVEMOVIE时带的)JPEG等等。MCI窗口底部有一个播放条,上面有播放/暂停(Play/Pause)按键、有显示播放进度的标尺,还有一个菜单,可调整窗口大小、声音大小,速度快慢等等,就和媒体播放器的界面一样。库VFW32.LIB中提供了MCI的所有功能,编译后生成的是真正的可执行文件,无需附加动态库和控件,如VBXOCX等。

源代码如下,其中黑体部分为关键代码,可以采用如下的命令行编译:

cl testmci.c user32.lib vfw32.lib

//testmci.c

#include <windows.h>

#include <vfw.h>

void SetClientRect(HWND hwnd, HWND hwndMCI)

{

RECT rect;

GetWindowRect(hwndMCI, &rect);

AdjustWindowRectEx(&rect, GetWindowLong(hwnd, GWL_STYLE), FALSE,

GetWindowLong(hwnd, GWL_EXSTYLE));

MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top,

TRUE);

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg,WPARAM wParam,

LPARAM lParam)

{

    switch(uMsg)

    {

        case MCIWNDM_NOTIFYPOS:

        case MCIWNDM_NOTIFYSIZE:

            SetClientRect(hwnd, (HWND)wParam);

            break;

        case WM_DESTROY:

            PostQuitMessage(0);

            break;

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return 0;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine,int nCmdShow)

{

    MSG msg;

    HWND hwnd;

    WNDCLASS wndClass;

    if (hPrevInstance == NULL)

    {

        memset(&wndClass, 0, sizeof(wndClass));

        wndClass.style = CS_HREDRAW | CS_VREDRAW;

        wndClass.lpfnWndProc = WndProc;

        wndClass.hInstance = hInstance;

        wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);

        wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

        wndClass.lpszClassName = "HELLO";

        if (!RegisterClass(&wndClass)) return FALSE;

    }

    hwnd = CreateWindow("HELLO", "HELLO",

                        WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,

                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

                        NULL, NULL, hInstance, NULL);

SetClientRect(hwnd, MCIWndCreate(hwnd, hInstance,

WS_VISIBLE|WS_CHILD|

MCIWNDF_SHOWALL|

MCIWNDF_NOTIFYSIZE|

MCIWNDF_NOTIFYPOS, “c:\\test.avi”));

ShowWindow(hwnd, nCmdShow);

UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))

        DispatchMessage(&msg);

    return msg.wParam;

}

运行时文件C:\test.avi必须准备好,当然,你可以改成其它的文件名。其运行结果如图10.5所示。

10.5  TestMCI的运行结果

该程序非常简单,所有的代码加在一起不超过60行,其关键部分只有一个MCIWndCreate函数,细节就不介绍了,有兴趣的读者可以参看VC的帮助。

  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多