界面效果:

-----------------------------------------------------------------------------------------------------------------

工程源代码下载地址:http://download.csdn.net/detail/luoshixian099/9257633

1.新建一个MFC工程,工程名VideoPlayer,选择使用静态库(方便以后的在其他的电脑上也能打开此软件),添加控件如上图所示。

修改控件的属性:

Picture控件ID--->IDC_VIEW;

滑动条控件 --->为此控件绑定一个CSliderCtrl类对象Slider。为了得到拖动滑动条可以到达“快进”和“快退”的效果。

2.首先需要OpenCV里面的CvvImage类,如果版本低于OpencCV2.2,可以直接调用这个类,如果高于此版本,需要重新定义这个类。CvvImage.cpp与CvvImage.h源代码见文章最后,把两个文件加入到工程中即可。

在VideoPlayerDlg.h文件中加入头文件和定义变量

[cpp] view plain copy  print?
  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "CvvImage.h"
  3. #include "afxcmn.h"
  4. using namespace cv;
  5. // CVideoPlayerDlg 对话框
  6. class CVideoPlayerDlg : public CDialog
  7. {
  8. ....
  9. //添加代码
  10. VideoCapture capture;
  11. HBITMAP hbitmap;
  12. CRect rect;
  13. CStatic* pStc; //标识图像显示的Picture控件
  14. CDC* pDC; //视频显示控件设备上下文
  15. HDC hDC; //视频显示控件设备句柄
  16. };

3.添加一副位图资源,用于界面美观;

4.在窗口初始化函数CVideoPlayerDlg::OnInitDialog()中添加代码如下:

[cpp] view plain copy  print?
  1. // TODO: 在此添加额外的初始化代码
  2. pStc=(CStatic *)GetDlgItem(IDC_VIEW);//IDC_VIEW为Picture控件ID
  3. pStc->GetClientRect(&rect);//Picture的大小传给矩形rect
  4. pDC=pStc->GetDC(); //得到Picture控件设备上下文
  5. hDC=pDC->GetSafeHdc(); //得到Picture控件设备上下文的句柄
  6. hbitmap = ::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP1));//加载位图资源
  7. pStc->ModifyStyle(1,SS_BITMAP);//修改控件的属性
  8. pStc->SetBitmap(hbitmap);//显示位图

5.双击“打开视频”按钮,为其添加响应函数

[cpp] view plain copy  print?
  1. void CVideoPlayerDlg::OnBnClickedButton1()
  2. {
  3. CString caption;
  4. GetDlgItemText(IDC_BUTTON1,caption);
  5. if (caption == _T("关闭视频"))    //关闭视频按钮
  6. {
  7. KillTimer(1);
  8. capture.release();
  9. SetDlgItemText(IDC_BUTTON1,_T("打开视频"));
  10. ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->EnableWindow(FALSE);  //滑动条失效
  11. ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->SetPos(0); //设置滑动条位置
  12. pStc->SetBitmap(hbitmap); //恢复位图资源
  13. return;
  14. }
  15. //打开视频,弹出通用对话框,选择要播放的视频文件
  16. string _Path;
  17. CFileDialog Openfiledlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, _T("Video Files (*.rmvb;*.avi)|*.rmvb;*.avi||"));
  18. if (Openfiledlg.DoModal() == IDOK) //弹出模态对话框
  19. {
  20. //CString类型转换为string类型
  21. CString  filepath;
  22. filepath=Openfiledlg.GetPathName();
  23. CStringA temp(filepath.GetBuffer(0));
  24. filepath.ReleaseBuffer();
  25. _Path = temp.GetBuffer(0);
  26. temp.ReleaseBuffer();
  27. }
  28. else
  29. return ;
  30. capture.open(_Path);  //打开视频
  31. if (!capture.isOpened())
  32. {
  33. MessageBox(_T("无法打开视频!"),_T("错误"));
  34. return;
  35. }
  36. else
  37. {
  38. ((CSliderCtrl *)GetDlgItem(IDC_SLIDER1))->EnableWindow(TRUE);  //激活滑动条
  39. Slider.SetRange(0,(int)capture.get(CV_CAP_PROP_FRAME_COUNT));//设置滑动条的范围,为视频的总帧数
  40. SetTimer(1,(unsigned int)(1000*1.0/capture.get(CV_CAP_PROP_FPS)),NULL); //定时器,定时时间和帧率一致
  41. SetDlgItemText(IDC_BUTTON1,_T("关闭视频"));//修改按钮的Caption
  42. }
  43. }

注意到要使用MFC中的CFileDialog类,用来弹出通用对话框,效果如下:

关于CFileDialog类的构造方法,可以参考MSDN

6.为主对话框添加定时器响应函数;

右击主对话框->属性->Messages->WM_TIMER

添加代码如下:

[cpp] view plain copy  print?
  1. void CVideoPlayerDlg::OnTimer(UINT_PTR nIDEvent)
  2. {
  3. if(1 == nIDEvent)
  4. {
  5. Mat img;
  6. capture>>img;  //取出一帧图像
  7. if (img.empty())
  8. {
  9. KillTimer(1);
  10. MessageBox(_T("视频结束"),_T("提示"));
  11. capture.release();
  12. }
  13. else
  14. {
  15. CvvImage m_CvvImage;
  16. IplImage frame(img);   //Mat 转IplImage
  17. m_CvvImage.CopyOf(&frame,1); //复制该帧图像
  18. m_CvvImage.DrawToHDC(hDC, &rect); //显示到设备的矩形框内
  19. Slider.SetPos( (int)capture.get(CV_CAP_PROP_POS_FRAMES));//设置视频的位置
  20. }
  21. }
  22. CDialog::OnTimer(nIDEvent);
  23. }

7.双击“滑动控件”为其添加响应函数,以到达“快进”和“快退”的效果

[cpp] view plain copy  print?
  1. void CVideoPlayerDlg::OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult)
  2. {
  3. LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
  4. // TODO: Add your control notification handler code here
  5. capture.set(CV_CAP_PROP_POS_FRAMES,Slider.GetPos());  //设置视频的起始帧
  6. *pResult = 0;
  7. }

8.编译运行,效果

------------------------------------------------------------------------------------

[cpp] view plain copy  print?
  1. //CvvImage.h
  2. #pragma once
  3. #ifndef CVVIMAGE_CLASS_DEF
  4. #define CVVIMAGE_CLASS_DEF
  5. #include "opencv.hpp"
  6. /* CvvImage class definition */
  7. class  CvvImage
  8. {
  9. public:
  10. CvvImage();
  11. virtual ~CvvImage();
  12. /* Create image (BGR or grayscale) */
  13. virtual bool  Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
  14. /* Load image from specified file */
  15. virtual bool  Load( const char* filename, int desired_color = 1 );
  16. /* Load rectangle from the file */
  17. virtual bool  LoadRect( const char* filename,
  18. int desired_color, CvRect r );
  19. #if defined WIN32 || defined _WIN32
  20. virtual bool  LoadRect( const char* filename,
  21. int desired_color, RECT r )
  22. {
  23. return LoadRect( filename, desired_color,
  24. cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
  25. }
  26. #endif
  27. /* Save entire image to specified file. */
  28. virtual bool  Save( const char* filename );
  29. /* Get copy of input image ROI */
  30. virtual void  CopyOf( CvvImage& image, int desired_color = -1 );
  31. virtual void  CopyOf( IplImage* img, int desired_color = -1 );
  32. IplImage* GetImage() { return m_img; };
  33. virtual void  Destroy(void);
  34. /* width and height of ROI */
  35. int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
  36. int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
  37. int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
  38. virtual void  Fill( int color );
  39. /* draw to highgui window */
  40. virtual void  Show( const char* window );
  41. #if defined WIN32 || defined _WIN32
  42. /* draw part of image to the specified DC */
  43. virtual void  Show( HDC dc, int x, int y, int width, int height,
  44. int from_x = 0, int from_y = 0 );
  45. /* draw the current image ROI to the specified rectangle of the destination DC */
  46. virtual void  DrawToHDC( HDC hDCDst, RECT* pDstRect );
  47. #endif
  48. protected:
  49. IplImage*  m_img;
  50. };
  51. typedef CvvImage CImage;
  52. #endif

--------------------------------------------

[cpp] view plain copy  print?
  1. //CvvImage.cpp
  2. #include "StdAfx.h"
  3. #include "CvvImage.h"
  4. //
  5. // Construction/Destruction
  6. //
  7. CV_INLINE RECT NormalizeRect( RECT r );
  8. CV_INLINE RECT NormalizeRect( RECT r )
  9. {
  10. int t;
  11. if( r.left > r.right )
  12. {
  13. t = r.left;
  14. r.left = r.right;
  15. r.right = t;
  16. }
  17. if( r.top > r.bottom )
  18. {
  19. t = r.top;
  20. r.top = r.bottom;
  21. r.bottom = t;
  22. }
  23. return r;
  24. }
  25. CV_INLINE CvRect RectToCvRect( RECT sr );
  26. CV_INLINE CvRect RectToCvRect( RECT sr )
  27. {
  28. sr = NormalizeRect( sr );
  29. return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top );
  30. }
  31. CV_INLINE RECT CvRectToRect( CvRect sr );
  32. CV_INLINE RECT CvRectToRect( CvRect sr )
  33. {
  34. RECT dr;
  35. dr.left = sr.x;
  36. dr.top = sr.y;
  37. dr.right = sr.x + sr.width;
  38. dr.bottom = sr.y + sr.height;
  39. return dr;
  40. }
  41. CV_INLINE IplROI RectToROI( RECT r );
  42. CV_INLINE IplROI RectToROI( RECT r )
  43. {
  44. IplROI roi;
  45. r = NormalizeRect( r );
  46. roi.xOffset = r.left;
  47. roi.yOffset = r.top;
  48. roi.width = r.right - r.left;
  49. roi.height = r.bottom - r.top;
  50. roi.coi = 0;
  51. return roi;
  52. }
  53. void  FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
  54. {
  55. assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
  56. BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
  57. memset( bmih, 0, sizeof(*bmih));
  58. bmih->biSize = sizeof(BITMAPINFOHEADER);
  59. bmih->biWidth = width;
  60. bmih->biHeight = origin ? abs(height) : -abs(height);
  61. bmih->biPlanes = 1;
  62. bmih->biBitCount = (unsigned short)bpp;
  63. bmih->biCompression = BI_RGB;
  64. if( bpp == 8 )
  65. {
  66. RGBQUAD* palette = bmi->bmiColors;
  67. int i;
  68. for( i = 0; i < 256; i++ )
  69. {
  70. palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
  71. palette[i].rgbReserved = 0;
  72. }
  73. }
  74. }
  75. CvvImage::CvvImage()
  76. {
  77. m_img = 0;
  78. }
  79. void CvvImage::Destroy()
  80. {
  81. cvReleaseImage( &m_img );
  82. }
  83. CvvImage::~CvvImage()
  84. {
  85. Destroy();
  86. }
  87. bool  CvvImage::Create( int w, int h, int bpp, int origin )
  88. {
  89. const unsigned max_img_size = 10000;
  90. if( (bpp != 8 && bpp != 24 && bpp != 32) ||
  91. (unsigned)w >=  max_img_size || (unsigned)h >= max_img_size ||
  92. (origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
  93. {
  94. assert(0); // most probably, it is a programming error
  95. return false;
  96. }
  97. if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h )
  98. {
  99. if( m_img && m_img->nSize == sizeof(IplImage))
  100. Destroy();
  101. /* prepare IPL header */
  102. m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 );
  103. }
  104. if( m_img )
  105. m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
  106. return m_img != 0;
  107. }
  108. void  CvvImage::CopyOf( CvvImage& image, int desired_color )
  109. {
  110. IplImage* img = image.GetImage();
  111. if( img )
  112. {
  113. CopyOf( img, desired_color );
  114. }
  115. }
  116. #define HG_IS_IMAGE(img)
  117. ((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) &&
  118. ((IplImage*)img)->imageData != 0) //以上三行 是一行
  119. void  CvvImage::CopyOf( IplImage* img, int desired_color )
  120. {
  121. if( HG_IS_IMAGE(img) )
  122. {
  123. int color = desired_color;
  124. CvSize size = cvGetSize( img );
  125. if( color < 0 )
  126. color = img->nChannels > 1;
  127. if( Create( size.width, size.height,
  128. (!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8,
  129. img->origin ))
  130. {
  131. cvConvertImage( img, m_img, 0 );
  132. }
  133. }
  134. }
  135. bool  CvvImage::Load( const char* filename, int desired_color )
  136. {
  137. IplImage* img = cvLoadImage( filename, desired_color );
  138. if( !img )
  139. return false;
  140. CopyOf( img, desired_color );
  141. cvReleaseImage( &img );
  142. return true;
  143. }
  144. bool  CvvImage::LoadRect( const char* filename,
  145. int desired_color, CvRect r )
  146. {
  147. if( r.width < 0 || r.height < 0 ) return false;
  148. IplImage* img = cvLoadImage( filename, desired_color );
  149. if( !img )
  150. return false;
  151. if( r.width == 0 || r.height == 0 )
  152. {
  153. r.width = img->width;
  154. r.height = img->height;
  155. r.x = r.y = 0;
  156. }
  157. if( r.x > img->width || r.y > img->height ||
  158. r.x + r.width < 0 || r.y + r.height < 0 )
  159. {
  160. cvReleaseImage( &img );
  161. return false;
  162. }
  163. /* truncate r to source image */
  164. if( r.x < 0 )
  165. {
  166. r.width += r.x;
  167. r.x = 0;
  168. }
  169. if( r.y < 0 )
  170. {
  171. r.height += r.y;
  172. r.y = 0;
  173. }
  174. if( r.x + r.width > img->width )
  175. r.width = img->width - r.x;
  176. if( r.y + r.height > img->height )
  177. r.height = img->height - r.y;
  178. cvSetImageROI( img, r );
  179. CopyOf( img, desired_color );
  180. cvReleaseImage( &img );
  181. return true;
  182. }
  183. bool  CvvImage::Save( const char* filename )
  184. {
  185. if( !m_img )
  186. return false;
  187. cvSaveImage( filename, m_img );
  188. return true;
  189. }
  190. void  CvvImage::Show( const char* window )
  191. {
  192. if( m_img )
  193. cvShowImage( window, m_img );
  194. }
  195. void  CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
  196. {
  197. if( m_img && m_img->depth == IPL_DEPTH_8U )
  198. {
  199. uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
  200. BITMAPINFO* bmi = (BITMAPINFO*)buffer;
  201. int bmp_w = m_img->width, bmp_h = m_img->height;
  202. FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
  203. from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
  204. from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
  205. int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
  206. int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
  207. SetDIBitsToDevice(
  208. dc, x, y, sw, sh, from_x, from_y, from_y, sh,
  209. m_img->imageData + from_y*m_img->widthStep,
  210. bmi, DIB_RGB_COLORS );
  211. }
  212. }
  213. void  CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect )
  214. {
  215. if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData )
  216. {
  217. uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
  218. BITMAPINFO* bmi = (BITMAPINFO*)buffer;
  219. int bmp_w = m_img->width, bmp_h = m_img->height;
  220. CvRect roi = cvGetImageROI( m_img );
  221. CvRect dst = RectToCvRect( *pDstRect );
  222. if( roi.width == dst.width && roi.height == dst.height )
  223. {
  224. Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
  225. return;
  226. }
  227. if( roi.width > dst.width )
  228. {
  229. SetStretchBltMode(
  230. hDCDst,           // handle to device context
  231. HALFTONE );
  232. }
  233. else
  234. {
  235. SetStretchBltMode(
  236. hDCDst,           // handle to device context
  237. COLORONCOLOR );
  238. }
  239. FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
  240. ::StretchDIBits(
  241. hDCDst,
  242. dst.x, dst.y, dst.width, dst.height,
  243. roi.x, roi.y, roi.width, roi.height,
  244. m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
  245. }
  246. }
  247. void  CvvImage::Fill( int color )
  248. {
  249. cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) );
  250. }

MFC视频播放器制作(OpenCV)相关推荐

  1. java视频播放器制作_java创建简易视频播放器

    java创建简易视频播放器 发布时间:2020-09-23 04:28:09 来源:脚本之家 阅读:98 作者:南柯一梦xihe 最近有个多媒体的作业,要求使用visualC++和OpenCV编写一个 ...

  2. Java 视频播放器制作,包含代码流程和资源需求。

    简单说明 技术方面还请各位海涵,代码和资源引用还有下载方式全部在这里了,这是一个利用Java Swing实现一个简单的视频播放器.由于视频播放器需要解码,这里引用的Java媒体框架(JMF)完成视频解 ...

  3. MFC 视频播放器实现局部放大功能

    这里介绍一种从MFC获取视频播放框并拉大的方法(还可以用一种在渲染部分拉大画布的方法) 其原理其实很简单,就是使用MoveWindow()的方法来进行放大和移动. 这里用的是鼠标双击后放大鼠标当前位置 ...

  4. QT5视频播放器制作

    这里使用QT自带的QMediaPlayer QMediaPlayer是对底层播放框架DirectShowPlayerService的封装,具体格式依赖播放框架,Windows上就是DirectShow ...

  5. 学雷前辈暑期小学期课简单视频播放器制作笔记(二)

    因为论文的方向分了(是的,是分的,不是自己选的,个中原因一言难尽.研究生毕设,刚开始,12月份答辩,之前做的全是内容开发,虽然很绝望但是还是要一点点做,论文方向是HEVC的编码优化,目前没啥思路,看了 ...

  6. 基于MFC视频播放器

    效果图如下:

  7. Python+QT+Selenium制作在线视频播放器

    最近突然想做一个视频播放器,可以在线看视频,关键还没用广告,不用会员,下面给大家介绍一下怎么制作 工具: Python Qt phantomjs 先给大家展示一下效果 下面上代码 导入库: from ...

  8. C++ OpenCV制作视频播放器

    目录 一:视频播放效果展示 二:完整源码分享 一:视频播放效果展示 1.1 点击开始播放按钮,能够播放视频 1.2 点击暂停播放 视频停在某一帧画面 同时按钮文本改变为继续播放       以便用户继 ...

  9. OpenCV C++案例实战二十一《制作视频播放器》

    OpenCV C++案例实战二十一<制作视频播放器> 前言 一.源码 二.效果 总结 前言 本文将使用OpenCV C++ 制作简易视频播放器,用于实现视频播放基本功能. 1.通过创建滑动 ...

最新文章

  1. 利用Use Case为系统行为建模(3)
  2. Python中的sorted函数以及operator.itemgetter函数
  3. 【Python数据挖掘课程】三.Kmeans聚类代码实现、作业及优化
  4. ViewPager的事件冲突的解决
  5. UVA208Firetruck 消防车(图的路径搜索)
  6. python word2vec 移植_真实资讯语料下的Word2Vec的迁移实践:Tag2Vec
  7. Linux/windows下java调用lingo
  8. Aegisub制作字幕从入门到精通:制作srt字幕,制作ass字幕,压制字幕和视频
  9. 使用MATLAB任意修改图片像素大小
  10. uniapp实现苹果支付流程
  11. 没错,Linux需要更多的憎恨者
  12. 瑞星2005升级问题汇总
  13. 使用css animation动画做边框闪动效果
  14. 数字时代,互联网企业的组织形态
  15. 连续被爆押金退款难  共享汽车会否走向和共享单车一样的宿命?
  16. (三十 :2021.01.11)MICCAI 2018 追踪之论文纲要(上)
  17. rich-text 富文本标签
  18. 【004 关键字】extern “C“的作用是什么?
  19. OFDM--IDFT实现
  20. Springboot 对接苹果内购代码

热门文章

  1. 第一次使用ESP8266_01S
  2. layui省市区的实现,及编辑时如何返显
  3. 山区灭火机器人_帅气!池州市首台消防灭火机器人正式投入基层执勤
  4. matlab求解LP问题
  5. git 与github配置(老师详细版)
  6. js实现刷新当前页面
  7. 1.深入.NET框架
  8. 【收藏】如何优雅的在 Python设置报警通知(邮件、短信、电脑外放声音)
  9. 【银河麒麟V10】【服务器】IO调度算法与性能分析
  10. PHP开发小技巧①⑥—提取富文本字符串中的文本内容