opencv + vs2017 mfc程序播放视频

opencv配置详见上一边文章

同样在MFCApplication1Dlg中新增一个按钮

对话框继承于哪个类不重要,反正只用到客户区,因为失误继承于htmldialog

h文件中添加VideoCapture

#include<opencv2\opencv.hpp>
#include<opencv2\highgui.hpp>

using namespace cv;


// CMFCApplication1Dlg 对话框
class CMFCApplication1Dlg : public CDHtmlDialog
{
// 构造
public:
    CMFCApplication1Dlg(CWnd* pParent = nullptr);    // 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_MFCAPPLICATION1_DIALOG, IDH = IDR_HTML_MFCAPPLICATION1_DIALOG };
#endif

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

    HRESULT OnButtonOK(IHTMLElement *pElement);
    HRESULT OnButtonCancel(IHTMLElement *pElement);

// 实现
protected:
    HICON m_hIcon;
    VideoCapture capture;

    // 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
    DECLARE_DHTML_EVENT_MAP()
public:
    afx_msg void OnBnClickedButton1();
    afx_msg void OnBnClickedButton2();
    afx_msg void OnTimer(UINT_PTR nIDEvent);
};

如上重要的是VideoCapture capture;和afx_msg void OnTimer(UINT_PTR nIDEvent);

分别为定义VideoCapture用来处理视频中每一帧,OnTimer用来播放每一帧

cpp文件中加入定时器定时器的响应

BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDHtmlDialog)
    ON_WM_SYSCOMMAND()
    ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)
    ON_BN_CLICKED(IDC_BUTTON2, &CMFCApplication1Dlg::OnBnClickedButton2)
    ON_WM_TIMER()
END_MESSAGE_MAP()

如上如上重要的是

    ON_BN_CLICKED(IDC_BUTTON2, &CMFCApplication1Dlg::OnBnClickedButton2)
    ON_WM_TIMER()

用来响应button2的dian点击事件的响应和定时器的响应

cpp文件中继续添加响应函数

int Mat2CImage(Mat *mat, CImage &img) {
    if (!mat || mat->empty())
        return -1;
    int nBPP = mat->channels() * 8;
    img.Create(mat->cols, mat->rows, nBPP);
    if (nBPP == 8)
    {
        static RGBQUAD pRGB[256];
        for (int i = 0; i < 256; i++)
            pRGB[i].rgbBlue = pRGB[i].rgbGreen = pRGB[i].rgbRed = i;
        img.SetColorTable(0, 256, pRGB);
    }
    uchar* psrc = mat->data;
    uchar* pdst = (uchar*)img.GetBits();
    int imgPitch = img.GetPitch();
    for (int y = 0; y < mat->rows; y++)
    {
        memcpy(pdst, psrc, mat->cols*mat->channels());//mat->step is incorrect for those images created by roi (sub-images!)
        psrc += mat->step;
        pdst += imgPitch;
    }

    return 0;
}

void CMFCApplication1Dlg::OnBnClickedButton2()
{
    // TODO: 在此添加控件通知处理程序代码

    capture.open("C:\\Users\\Dell\\Desktop\\a\\b.mp4");//随便指定一个视频所在路径

  if (capture.isOpened()) {
    }
    else {
        AfxMessageBox(_T("打开失败"));
        return;
    }

    SetTimer(1, (unsigned int)(1000 * 1.0 / capture.get(CV_CAP_PROP_FPS)), NULL);//按视频帧率设置定时器,所以 ON_WM_TIMER()的设置很重要,不然不会响应定时事件
}

void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent)
{
    if (1 == nIDEvent)
    {
        Mat matImg;
        capture >> matImg;  //取出一帧图像
        if (matImg.empty())
        {
            KillTimer(1);
            MessageBox(_T("视频结束"), _T("提示"));
            capture.release();
        }
        else
        {
            CImage img;
            RECT   rt;

            Mat2CImage(&matImg, img);
            GetClientRect(&rt);

            rt.bottom -= 40;

            img.Draw(this->GetDC()->GetSafeHdc(), rt);
        }
    }

    CDHtmlDialog::OnTimer(nIDEvent);
}

还没有加入开始、暂停,拖动进度条的控制控制,主要用到

capture.set(CV_CAP_PROP_POS_FRAMES,XXX.GetPos()); //设置视频的起始帧

XXX就是一个进度条

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值