c++中类的封装

在软件的设计中,使用类的概念可以提高程序的简洁性及可读性,以及一系列好处。在软件设计中,需要实现多个摄像头的摄像及显示,我试图把视频的设备获取,创建DirectShow Filter,连接DirectShow Filter,对视频的控制等等操作封装到一个CVideo类中,这样程序简洁明了,易于操作,不容易出错,提高了程序的鲁棒性。

1. 类的定义:

在现实世界中,经常有属于同一类的对象。例如,你的自行车只是世界上很多自行车中的一辆。在面向对象软件中,也有很多共享相同特征的不同的对象:矩形、雇用记录、视频剪辑等。可以利用这些对象的相同特征为它们建立一个蓝图。对象的软件蓝图称为类。

类是定义同一类所有对象的变量和方法的蓝图或原型。例如,可以建立一个定义包含当前档位等实例变量的自行车类。这个类也定义和提供了实例方法(变档、刹车)的实现。实例变量的值由类的每个实例提供。因此,当你创建自行车类以后,必须在使用之前对它进行实例化。当创建类的实例时,就建立了这种类型的一个对象,然后系统为类定义的实例变量分配内存。然后可以调用对象的实例方法实现一些功能。相同类的实例共享相同的实例方法。

C++ 程序设计允许程序员使用类(class)定义特定程序中的数据类型。这些数据类型的实例被称为对象,这些事例可以包含程序员定义的成员变量、常量、成员函数,以及重载的运算符。语法上,类是C中结构体(struct)的扩展,结构体不能包含函数以及重载的运算符。

2. 区别:类和对象

对象和类的说明很相似。实际上,类和对象之间的差别经常是一些困惑的起源。在现实世界中很明显,类不是它描述的对象 自行车的蓝图不是自行车。但是在软件中就有点难区分类和对象。这部分是由于软件对象只是现实世界的电子模型或抽象概念。但是也由于很多人用“对象”指类和它们的实例这两者。

3. VideoCapture中封装类的具体实现

(a)利用ClassWizard新建一个基于CWndMFC类,类名CVideo

(b)Attributes中定义变量IGraphBuilder * pGraph;用于创建Graph Filter Manager

定义ICaptureGraphBuilder2 *pBuilder2;用于创建Graph Stream

定义IMediaControl *pControl;用于媒体流的控制

定义IMediaEvent   *pEvent;用于控制媒体流事件

定义IVideoWindow  *pWindow;视频显示的窗口

(c)在类定义的头文件中,变量是不能被初始化的,变量的初始化在Video类的构造函数中,在CPP文件中,即CVideo::CVideo()中,定义5个指针变量的初始值为NULL,指针定义的使用之前一定要初始化,这里为NULL

CVideo的成员函数

GetInterface()创建Filter Graph的接口

GetDevice()获得系统的摄像头设备

MediaControl()对媒体流进行控制

Void CVideo::GetInterface() //创建Filter Graph的接口

{

//Graph接口的创建

HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,

IID_IGraphBuilder, (void **) &pGraph);

if (FAILED(hr))

        MessageBox("create graph failed");

// capture graph builder的创建

    hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,

IID_ICaptureGraphBuilder2, (void **) &pBuilder2);

if(FAILED(hr))

MessageBox("create capture graph failed");

// 把filter graph 连接到 capture graph

    hr = pBuilder2->SetFiltergraph(pGraph);

// 获得媒体控制和媒体窗口

    hr = pGraph->QueryInterface(IID_IMediaControl,(LPVOID *) &pControl);

    if (FAILED(hr))

        MessageBox("error");

    hr = pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *) &pWindow);

    if (FAILED(hr))

        MessageBox("error");

    hr = pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *) &pEvent);

    if (FAILED(hr))

        MessageBox("error");

}

Void CVideo:: GetDevice() //获得系统的摄像头设备

{

ICreateDevEnum *pDevEnum = NULL;//创建一个设备枚举器

hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,

IID_ICreateDevEnum, (void **) &pDevEnum);

if(FAILED(hr))

MessageBox("error");

IEnumMoniker *pClassEnum = NULL;//创建一个设备媒体类型

hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);

if(FAILED(hr))

MessageBox("error");

if(pClassEnum==NULL)

{

MessageBox("pClassEnum=NULL");

}

// Use the first video capture device on the device list.

    // Note that if the Next() call succeeds but there are no monikers,

    // it will return S_FALSE (which is not a failure).  Therefore, we

    // check that the return code is S_OK instead of using SUCCEEDED() macro.

IMoniker *pMoniker =NULL; //创建一个媒体设备

IBaseFilter * pSrc = NULL; //指向设备的指针

ULONG cFetched;

int count = 0;

while(S_OK == (pClassEnum->Next(1,&pMoniker,&cFetched)))

{

//把设备绑定到设备指针

count++;

if(count == 1)

{

hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pSrc);

if(FAILED(hr))

MessageBox("pMoniker Failed");

}

}

}

4. 性能测试

以上就是一个完整的摄像机视频类,在主类的程序中如果需要添加一个摄像头视频,只要在类中定义一个CVideo的类对象即可。CVideo类的对象完成摄像头的Filter创建,连接,如果需要对摄像头视频进行控制,直接调用CVideo类对象的成员函数。如果有多个视频,各个视频之间的控制不会打架。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值