directshow摄像头录像_open camera 使用方法

directshow摄像头录像_open camera 使用方法Win1064+VS2012工程下载:http://download.csdn.net/detail/yulinxx/9263639建一个基于Dialog的MFC程序,而局如下:一个PIC控件,用于显示摄像头捕捉画面,几个按钮创建一个C++类,类名为:CCamera在CCamera.h中,需要包含#include#include”qedit.h”

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

Win10 64 + VS2012

工程下载:
http://download.csdn.net/detail/yulinxx/9263639

建一个基于Dialog的MFC程序,而局如下:
一个PIC控件,用于显示摄像头捕捉画面,几个按钮
这里写图片描述

创建一个C++类,类名为:CCamera
在CCamera.h中,需要包含

#include <atlbase.h>
#include "qedit.h"
#include "dshow.h"
#include <windows.h>

在#include “qedit.h”之前,需要添加如下代码,避免qedit.h报错:

#pragma include_alias( "dxtrans.h", "qedit.h" )
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__

CCamera.h 全文为:

#pragma once



#pragma include_alias( "dxtrans.h", "qedit.h" )
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__

#include <atlbase.h>
#include "qedit.h"
#include "dshow.h"
#include <windows.h>



#define MYFREEMEDIATYPE(mt) { 
   if ((mt).cbFormat != 0) \
{CoTaskMemFree((PVOID)(mt).pbFormat);    \
    (mt).cbFormat =0;                        \
    (mt).pbFormat = NULL;                    \
}                                            \
    if ((mt).pUnk != NULL)                        \
{                                            \
    (mt).pUnk->Release();                    \
    (mt).pUnk = NULL;                        \
}}                  


class CCamera
{
public:
    CCamera(void);
    ~CCamera(void);


private:
    CImage m_image;
    bool m_bConnected;
    int m_nWidth;
    int m_nHeight;
    bool m_bLock;
    bool m_bChanged;
    long m_nBufferSize;

    CComPtr<IGraphBuilder> m_pGraphBuilder;
    CComPtr<IBaseFilter> m_pDeviceFilter;
    CComPtr<IMediaControl> m_pMediaControl;
    CComPtr<IBaseFilter> m_pSampleGrabberFilter;
    CComPtr<ISampleGrabber> m_pSampleGrabber;
    CComPtr<IPin> m_pGrabberInput;
    CComPtr<IPin> m_pGrabberOutput;
    CComPtr<IPin> m_pCameraOutput;
    CComPtr<IMediaEvent> m_pMediaEvent;
    CComPtr<IBaseFilter> m_pNullFilter;
    CComPtr<IPin> m_pNullInputPin;


    bool BindFilter(int nCameraIndex, IBaseFilter **pFilter);


public:
    static int CameraCount(); 

    bool OpenCamera(int nCamID, bool bDisplayProperties=true, int nWidth =320, int nHeight =240);

    CImage* QueryFrame(); 
};

CCamera.cpp 全文为

#include "stdafx.h"
#include "Camera.h"

#pragma comment(lib,"Strmiids.lib") 

CCamera::CCamera(void)
{
}


CCamera::~CCamera(void)
{
}



bool CCamera::BindFilter(int nCameraIndex, IBaseFilter **pFilter)
{
    if (nCameraIndex < 0)
        return false;

    // enumerate all video capture devices
    CComPtr<ICreateDevEnum> pCreateDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
        IID_ICreateDevEnum, (void**)&pCreateDevEnum);
    if (hr != NOERROR)
    {
        return false;
    }

    CComPtr<IEnumMoniker> pEm;      // This will access the actual devices
    // 为指定的Filter注册类型目录创建一个枚举器,并获得 IEnumMoniker接口 (Video Capture Sources )
    // 可以访问捕捉设备的列表了
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
    if (hr != NOERROR) 
    {
        return false;
    }

    pEm->Reset();       // Go to the start of the enumerated list
    ULONG cFetched;
    IMoniker *pM;
    int index =0;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= nCameraIndex)
    {
        IPropertyBag *pBag;
        // BindToStorage之后就可以访问设备标识的属性集了。
        // Binds to the storage for the specified object. Unlike the IMoniker::BindToObject method, 
        // this method does not activate the object identified by the moniker.
        hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);
        if(SUCCEEDED(hr)) 
        {
            VARIANT var;
            var.vt = VT_BSTR;
            hr = pBag->Read(L"FriendlyName", &var, NULL);
            if (hr == NOERROR) 
            {
                if (index == nCameraIndex)
                {
                    // BindToObject将某个设备标识绑定到一个DirectShow Filter,
                    // 然后调用IFilterGraph::AddFilter加入到Filter Graph中,这个设备就可以参与工作了
                    // 调用IMoniker::BindToObject建立一个和选择的device联合的filter,
                    // 并且装载filter的属性(CLSID,FriendlyName, and DevicePath)。
                    // Binds to the specified object. The binding process involves finding the object, 
                    // putting it into the running state if necessary, 
                    // and providing the caller with a pointer to a specified interface on the identified object.
                    pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
                }
                SysFreeString(var.bstrVal);
            }
            pBag->Release();
        }
        pM->Release();
        index++;
    }

    pCreateDevEnum = NULL;
    return true;
}




int CCamera::CameraCount()
{
    CoInitialize(NULL);
    int nCount =0;

    // enumerate all video capture devices
    CComPtr<ICreateDevEnum> pCreateDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
        IID_ICreateDevEnum, (void**)&pCreateDevEnum);

    CComPtr<IEnumMoniker> pEm;
    // 使用接口方法ICreateDevEnum::CreateClassEnumerator为指定的Filter注册类型目录创建一个枚举器,并获得 IEnumMoniker接口;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
    if (hr != NOERROR) 
    {
        return nCount;
    }

    pEm->Reset();
    ULONG cFetched;
    IMoniker *pM;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {
        nCount++;
    }

    pCreateDevEnum = NULL;
    pEm = NULL;
    return nCount;
}



bool CCamera::OpenCamera(int nCamID, bool bDisplayProperties/*=true*/, int nWidth /*=320*/, int nHeight /*=240*/)
{
    HRESULT hr = S_OK;

    CoInitialize(NULL);
    // 调用CoCreateInstance来创建筛选器表管理器.筛选器表管理器由一个进程内的DLL提供,所以执行上下文是 CLSCTX_INPROC_SERVER
    // 对CoCreateInstance的调用返回IGraphBuilder接口,它主要包含了生成筛选器表的方法。此例中用到的另两个接口为:
    // IMediaControl,作用是控制流。它包含了停止和启动表的方法
    // IMediaEvent,它包含的方法是从筛选器表管理器中得到事件。
    // 创建IGraphBuilder接口 Create the Filter Graph Manager. (用指定的类标识符创建一个Com对象)
    // Filter Graph Manager
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, 
        IID_IGraphBuilder, (void**)&m_pGraphBuilder);


    // IMediaControl接口,用来控制流媒体在Filter Graph中的流动,例如流媒体的启动和停止;
    hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void**) &m_pMediaControl);
    // IMediaEvent接口,该接口在Filter Graph发生一些事件时用来创建事件的标志信息并传送给应用程序
    hr = m_pGraphBuilder->QueryInterface(IID_IMediaEvent, (void**) &m_pMediaEvent);


    hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
        IID_IBaseFilter, (LPVOID*) &m_pNullFilter);

    hr = m_pGraphBuilder->AddFilter(m_pNullFilter, L"NullRenderer");


    hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, 
        IID_IBaseFilter, (LPVOID *)&m_pSampleGrabberFilter);

    // 查询得到组件对象上的接口
    hr = m_pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&m_pSampleGrabber);

    AM_MEDIA_TYPE   mt;
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
    mt.formattype = FORMAT_VideoInfo; 
    hr = m_pSampleGrabber->SetMediaType(&mt);

    MYFREEMEDIATYPE(mt);

    m_pGraphBuilder->AddFilter(m_pSampleGrabberFilter, L"Grabber");

    // Bind Device Filter. We know the device because the id was passed in
    BindFilter(nCamID, &m_pDeviceFilter);
    m_pGraphBuilder->AddFilter(m_pDeviceFilter, NULL);

    CComPtr<IEnumPins> pEnum;
    m_pDeviceFilter->EnumPins(&pEnum);

    hr = pEnum->Reset();    // The Reset method resets the enumeration sequence to the beginning.
    hr = pEnum->Next(1, &m_pCameraOutput, NULL);    // The Next method retrieves a specified number of pins in the enumeration sequence.

    pEnum = NULL; 
    m_pSampleGrabberFilter->EnumPins(&pEnum);
    pEnum->Reset();
    hr = pEnum->Next(1, &m_pGrabberInput, NULL); 

    pEnum = NULL;
    m_pSampleGrabberFilter->EnumPins(&pEnum);
    pEnum->Reset();
    pEnum->Skip(1);
    hr = pEnum->Next(1, &m_pGrabberOutput, NULL); 

    pEnum = NULL;
    m_pNullFilter->EnumPins(&pEnum);
    pEnum->Reset();
    hr = pEnum->Next(1, &m_pNullInputPin, NULL);

    //SetCrossBar();

    if (bDisplayProperties) 
    {
        CComPtr<ISpecifyPropertyPages> pPages;

        HRESULT hr = m_pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages);
        if (SUCCEEDED(hr))
        {
            PIN_INFO PinInfo;
            m_pCameraOutput->QueryPinInfo(&PinInfo);

            CAUUID caGUID;
            pPages->GetPages(&caGUID);

            OleCreatePropertyFrame(NULL, 0, 0,
                L"Property Sheet", 1,
                (IUnknown **)&(m_pCameraOutput.p),
                caGUID.cElems,
                caGUID.pElems,
                0, 0, NULL);
            CoTaskMemFree(caGUID.pElems);
            PinInfo.pFilter->Release();
        }
        pPages = NULL;
    }
    else 
    {
        //////////////////////////////////////////////////////////////////////////////
        // 加入由 lWidth和lHeight设置的摄像头的宽和高 的功能,默认320*240
        // by flymanbox @2009-01-24
        //////////////////////////////////////////////////////////////////////////////
        int _Width = nWidth, _Height = nHeight;
        IAMStreamConfig* iconfig = NULL;
        hr = m_pCameraOutput->QueryInterface(IID_IAMStreamConfig, (void**)&iconfig);   

        AM_MEDIA_TYPE* pmt;    
        if(iconfig->GetFormat(&pmt) !=S_OK) 
        {
            //printf("GetFormat Failed ! \n");
            return false;   
        }

        VIDEOINFOHEADER* phead;
        if ( pmt->formattype == FORMAT_VideoInfo)   
        {   
            phead=( VIDEOINFOHEADER*)pmt->pbFormat;   
            phead->bmiHeader.biWidth = _Width;   
            phead->bmiHeader.biHeight = _Height;   
            if(( hr=iconfig->SetFormat(pmt)) != S_OK )   
            {
                return false;
            }
        }   

        iconfig->Release();   
        iconfig=NULL;   
        MYFREEMEDIATYPE(*pmt);
    }

    hr = m_pGraphBuilder->Connect(m_pCameraOutput, m_pGrabberInput);
    hr = m_pGraphBuilder->Connect(m_pGrabberOutput, m_pNullInputPin);

    if (FAILED(hr))
    {
        switch(hr)
        {
        case VFW_S_NOPREVIEWPIN :
            break;
        case E_FAIL :
            break;
        case E_INVALIDARG :
            break;
        case E_POINTER :
            break;
        }
    }

    // The SetBufferSamples method specifies whether to copy sample data into a buffer as it goes through the filter.
    m_pSampleGrabber->SetBufferSamples(TRUE);

    // The SetOneShot method specifies whether the Sample Grabber filter halts after the filter receives a sample.
    m_pSampleGrabber->SetOneShot(TRUE);

    hr = m_pSampleGrabber->GetConnectedMediaType(&mt);
    if(FAILED(hr))
        return false;

    VIDEOINFOHEADER *videoHeader;
    videoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
    m_nWidth = videoHeader->bmiHeader.biWidth;
    m_nHeight = videoHeader->bmiHeader.biHeight;
    m_bConnected =true;

    pEnum = NULL;
    return true;
}

CImage* CCamera::QueryFrame()
{
    long evCode;
    long size =0;

    m_pMediaControl->Run();         // 运行filter
    // 当筛选器运行时,数据从筛选器中移出,并以视频和音频的方式还原出来。
    // 播放会启动另一个线程。您可以调用IMediaEvent::WaitForCompletion方法。

    // 等待结束
    m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);

    m_pSampleGrabber->GetCurrentBuffer(&size, NULL);    // If pBuffer is NULL, this parameter receives the required buffer size

    //if the buffer size changed
    if (size != m_nBufferSize)
    {
        m_nBufferSize = size;
        m_image.Create(m_nWidth,m_nHeight,24);
    }
    if(m_image.IsNull())
    {
        return 0;
    }
    byte*q = NULL;
    byte*p = new byte[m_nWidth*m_nHeight*3];
    m_pSampleGrabber->GetCurrentBuffer(&m_nBufferSize, (long*)p);   // If pBuffer is not NULL, set this parameter equal to the size of the buffer, in bytes.

    for(int y=0, z=m_nHeight-1; y<m_nHeight,z>=0; y++,z--)
    {
        q = (byte*)m_image.GetPixelAddress(0,z);
        memcpy(q,&p[m_nWidth*3*y],m_nWidth*3);
    }
    delete []p;
    return &m_image;
}

”开启摄像头“”开启摄像头(选择性)“需互斥,
即点击其中一个按钮后,需禁用另一个按钮
选择性,可以在开启前,选择分辨率等参数

在Dlg.cpp中,点击”开启摄像头“按钮,响应如下代码:

    GetDlgItem(IDC_BTN_VIEW)->EnableWindow(TRUE);
    GetDlgItem(IDC_BTN_VIEW2)->EnableWindow(FALSE);

    int nCameraCount = CCamera::CameraCount();
    m_vecCamera.resize(nCameraCount);

    if (!m_vecCamera[nCameraCount-1].OpenCamera(nCameraCount-1, false, 640, 480))
    {
        AfxMessageBox(_T("打开摄像头失败"));
        return;
    }

    while (true)
    {
        if (m_bStop)
        {
            break;
        }
        m_pImageView = m_vecCamera[nCameraCount - 1].QueryFrame();
        OnDlgEvent();
        ShowPicture(m_pImageView, &m_wndStcView);
    }   

在Dlg.cpp中,点击”开启摄像头(选择性)“按钮,响应如下代码:

    GetDlgItem(IDC_BTN_VIEW)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_VIEW2)->EnableWindow(TRUE);

    int nCameraCount = CCamera::CameraCount();
    m_vecCamera.resize(nCameraCount);

    if (!m_vecCamera[nCameraCount-1].OpenCamera(nCameraCount-1, true, 640, 480))
    {
        AfxMessageBox(_T("打开摄像头失败"));
        return;
    }

    while (true)
    {
        if (m_bStop)
        {
            break;
        }
        m_pImageView = m_vecCamera[nCameraCount - 1].QueryFrame();
        OnDlgEvent();
        ShowPicture(m_pImageView, &m_wndStcView);
    }   

DShowCameraDlg.h 全文为:


// DShowCameraDlg.h : 头文件
//

#pragma once

#include <vector>

// CDShowCameraDlg 对话框
#include "Camera.h"
#include "afxwin.h"

class CDShowCameraDlg : public CDialogEx
{
// 构造
public:
    CDShowCameraDlg(CWnd* pParent = NULL);  // 标准构造函数

// 对话框数据
    enum { IDD = IDD_DSHOWCAMERA_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持


// 实现
protected:
    HICON m_hIcon;

    void ShowPicture(CImage* pImg,CStatic* pStcView);

    // 生成的消息映射函数
    virtual BOOL OnInitDialog();

    afx_msg void OnPaint();

    afx_msg void OnClose();
    afx_msg void OnBnClickedOk();
    afx_msg void OnBnClickedCancel();

    afx_msg void OnBnClickedBtnView();

    afx_msg void OnBnClickedBtnView2();

    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()


protected:
    BOOL m_bStop;

    CImage* m_pImageView;
    int m_nCameraCount;
    std::vector<CCamera> m_vecCamera;
    CStatic m_wndStcView;

};

DShowCameraDlg. cpp全文为:


// DShowCameraDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "DShowCamera.h"
#include "DShowCameraDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDShowCameraDlg 对话框


CDShowCameraDlg::CDShowCameraDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CDShowCameraDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_nCameraCount = -1;
    m_pImageView = NULL;
    m_bStop = FALSE;
}

void CDShowCameraDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_STC_VIEW, m_wndStcView);
}

BEGIN_MESSAGE_MAP(CDShowCameraDlg, CDialogEx)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BTN_VIEW, &CDShowCameraDlg::OnBnClickedBtnView)
    ON_WM_DESTROY()
    ON_WM_CLOSE()
    ON_BN_CLICKED(IDOK, &CDShowCameraDlg::OnBnClickedOk)
    ON_BN_CLICKED(IDCANCEL, &CDShowCameraDlg::OnBnClickedCancel)
    ON_BN_CLICKED(IDC_BTN_VIEW2, &CDShowCameraDlg::OnBnClickedBtnView2)
END_MESSAGE_MAP()


// CDShowCameraDlg 消息处理程序


void CDShowCameraDlg::ShowPicture(CImage* pImg,CStatic* pStcView)
{
    if(pImg == NULL) 
        return;

    int width = pImg->GetWidth();
    int height = pImg->GetHeight();
    CRect rectView;
    pStcView->GetClientRect(&rectView);
    CRect rt(rectView);
    CDC* dc = pStcView->GetDC();
    ASSERT(dc);

    CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH));
    //dc->FillRect(rt, pBrush);

    if(rectView.Height() * width > height * rectView.Width())
    {
        CPoint p1(0, (rectView.Height()-(rectView.Width()*height/width))/2);
        CPoint p2(rectView.Width(),(rectView.Height() - p1.y));
        rt.SetRect(p1,p2);
    }
    else
    {
        CPoint pt1((rectView.Width()-(rectView.Height()*width/height))/2,0);
        CPoint pt2(rectView.Width()-pt1.x, rectView.Height());
        rt.SetRect(pt1,pt2);
    }

    if (dc)
    {
        ::SetStretchBltMode(dc->m_hDC, HALFTONE);
        pImg->Draw(dc->m_hDC, rt);
    }
}



BOOL CDShowCameraDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    // 执行此操作
    SetIcon(m_hIcon, TRUE);         // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    // TODO: 在此添加额外的初始化代码

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。

void CDShowCameraDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // 使图标在工作区矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDShowCameraDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}


void OnDlgEvent()
{
    MSG msg;
    if (::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}


// 开启摄像头
void CDShowCameraDlg::OnBnClickedBtnView()
{
    GetDlgItem(IDC_BTN_VIEW)->EnableWindow(TRUE);
    GetDlgItem(IDC_BTN_VIEW2)->EnableWindow(FALSE);

    int nCameraCount = CCamera::CameraCount();
    m_vecCamera.resize(nCameraCount);

    if (!m_vecCamera[nCameraCount-1].OpenCamera(nCameraCount-1, false, 640, 480))
    {
        AfxMessageBox(_T("打开摄像头失败"));
        return;
    }

    while (true)
    {
        if (m_bStop)
        {
            break;
        }
        m_pImageView = m_vecCamera[nCameraCount - 1].QueryFrame();
        OnDlgEvent();
        ShowPicture(m_pImageView, &m_wndStcView);
    }   
}




void CDShowCameraDlg::OnBnClickedBtnView2()
{
    // TODO: 在此添加控件通知处理程序代码
    GetDlgItem(IDC_BTN_VIEW)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_VIEW2)->EnableWindow(TRUE);

    int nCameraCount = CCamera::CameraCount();
    m_vecCamera.resize(nCameraCount);

    if (!m_vecCamera[nCameraCount-1].OpenCamera(nCameraCount-1, true, 640, 480))
    {
        AfxMessageBox(_T("打开摄像头失败"));
        return;
    }

    while (true)
    {
        if (m_bStop)
        {
            break;
        }
        m_pImageView = m_vecCamera[nCameraCount - 1].QueryFrame();
        OnDlgEvent();
        ShowPicture(m_pImageView, &m_wndStcView);
    }   
}





void CDShowCameraDlg::OnClose()
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bStop = TRUE;

    CDialogEx::OnClose();
}


void CDShowCameraDlg::OnBnClickedOk()
{
    // TODO: 在此添加控件通知处理程序代码
    m_bStop = TRUE;

    CDialogEx::OnOK();
}


void CDShowCameraDlg::OnBnClickedCancel()
{
    // TODO: 在此添加控件通知处理程序代码
    m_bStop = TRUE;

    CDialogEx::OnCancel();
}

qedit.h (可网上下载)全文为:

这里写图片描述

这里写图片描述


获取摄像头所支持的所有分辨率:


std::vector<POINT> CCamera::GetAllSupportPix(int iDeviceID)
{
    HRESULT hr = S_OK;
    std::vector<POINT> vecPix;
    ICaptureGraphBuilder2* _pCapture = NULL;
    IBaseFilter* _pBF;

    hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
        IID_ICaptureGraphBuilder2, (void **)&_pCapture);
    if (FAILED(hr))
        return vecPix;

    if (!BindFilter(iDeviceID, &_pBF))
    {
        srelease(_pCapture);
        return vecPix;
    }
    IAMStreamConfig*  pStreamConfig;
    AM_MEDIA_TYPE *pmtConfig;
    hr = _pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, 0,_pBF, IID_IAMStreamConfig, (void**)&pStreamConfig); 
    if (FAILED(hr))
    {
        srelease(_pCapture);
        srelease(_pBF);
        return vecPix;
    }
    pStreamConfig->GetFormat(&pmtConfig);
    if (FAILED(hr))
    {
        srelease(_pCapture);
        srelease(_pBF);
        pStreamConfig->Release();
        return vecPix;
    }
    VIDEOINFOHEADER * vi = (VIDEOINFOHEADER*) pmtConfig->pbFormat;

    int iCount, iSize;
    VIDEO_STREAM_CONFIG_CAPS caps;
    pStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);

    AM_MEDIA_TYPE *pmtPV = NULL;
    for (int i = 0; i<iCount; ++i)
    {
        if (pStreamConfig->GetStreamCaps(i, &pmtPV, (BYTE*)&caps) == S_OK)
        {
            if (pmtPV->subtype == MEDIASUBTYPE_RGB24)
            {
                POINT pix = {caps.MaxOutputSize.cx,caps.MaxOutputSize.cy};
                vecPix.push_back(pix);
            }
            //FreeMediaType(*pmtPV);
        }
    }

    srelease(_pCapture);
    srelease(_pBF);
    //FreeMediaType(*pmtConfig);
    pStreamConfig->Release();
    return vecPix;
}


补充:
Camera.cpp 释放的时候
CCamera::~CCamera(void)

if(m_bConnected)
    {
        m_pMediaControl->Stop();
    }

    m_pGraphBuilder = NULL;
    m_pDeviceFilter = NULL;
    m_pMediaControl = NULL;
    m_pSampleGrabberFilter = NULL;
    m_pSampleGrabber = NULL;
    m_pGrabberInput = NULL;
    m_pGrabberOutput = NULL;
    m_pCameraOutput = NULL;
    m_pMediaEvent = NULL;
    m_pNullFilter = NULL;
    m_pNullInputPin = NULL;

    if(!m_image.IsNull())
    {
        m_image.Destroy();
    }

    m_bConnected = false;
    m_nWidth = 0;
    m_nHeight = 0;
    m_bLock = false;
    m_bChanged = false;
    m_nBufferSize = 0;
    CoUninitialize();
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/182880.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Windows:安装cygwin教程[通俗易懂]

    目录目录前言常见错误前言本篇文章参考这篇:cygwin安装但自从博主写后,这个东西发生了一些变化,因此,根据最新版的重新写了一遍。我们可以到Cygwin的官方网站下载Cygwin的安装程序或者直接使用来下载安来下载安装程序.下载完成后,运行setup.exe程序,首先是同意安装,第三方的软件在windows上不受信任,出现安装画面。直接点“下一步”,…

  • 免费公共DNS服务器大全

    免费公共DNS服务器大全港澳台地区DNS国外公共DNS老D推荐使用:目录国内常用公共DNS114DNS:(114.114.114.114;114.114.115.115)114DNS安全版 (114.114.114.119;114.114.115.119)114DNS家庭版 (114.114.114.110;114.114.115.110)阿里AliDNS:(223.5.5.5;&nbs…

  • base64编码图片 生成图片,返回地址[通俗易懂]

    base64编码图片 生成图片,返回地址[通俗易懂]publicfunctiontestPic() { $image=”data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAXFCAYAAABw+mVzAAAgAElEQVR4Xuzdd7w8VX3/8ZnZ3Xu/jW9DkCJWlGJNUFFRESyUYEElxh79qT9bYorRnyaxxKixJGpiSWwoisaCYkNUl

  • 范围管理_范围管理的获取方法

    范围管理_范围管理的获取方法一、范围管理的基本理解(1)包括确保项目做且只做所需的全部工作,已成功完成项目的各个过程。(2)项目范围管理需要做的工作》明确项目边界。》对项目执行工作进行监控。》防止项目范围发生蔓延。指对时间、成本和资源做相应调整,未经控制的产品或项目范围的扩大。(3)产品范围和项目范围》产品范围:产品、服务或结果的特性和功能。》项目范围:是否完成以项目管理计划、项目范围说明书、WBS、以及WBS字典作为衡量标准。产品范围是否完成以产品需求说明书作为衡量标准。二、规划范围管理1、项目范围管理计划的内

  • mimikatz行为免杀_易语言远程源码

    mimikatz行为免杀_易语言远程源码目录介绍环境准备处理报错生成32位生成64位下载360、360杀毒直接查杀关键字替换-失败去除注释,修改版本信息删除注释信息替换图标修改版本信息重新编译文件过杀软360家族腾讯电脑管家火绒在线查杀参考学习一下月师傅的文章介绍Mimikatz是一款能够从Windows认证(LSASS)的进程中获取内存,并且获取明文密码和NTLM哈希值的工具,攻击者可以借此漫游内网。也可以通过明文密码或者传递hash值来提权。因为这款工具特别出名所以被查杀的机率很大,我们可以通过github上的开源代码对其进行源码免

  • Mysql学习——MySQL导入导出.sql文件及常用命令

    Mysql学习——MySQL导入导出.sql文件及常用命令在日常学习和工作,难免不了使用Mysql数据库,有时候需要导入导出数据库,或者其中的数据表。下面是我自己整理的一些东西!

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号