一、项目需求

AR播放器:将一系列带透明通道的图片以一定的帧率连续显示,叠加载摄像头采集的画面之上,并播放声音。

此为最初级的AR技术,因为画面是事先渲染好的,固定不变的,所以实际上并不能实现“互动”,当然,配合画面摆出几个动作拍个照片还是可以。

二、解决方案

1、WinForm还是WPF?

关于摄像头操作,WinForm有很多开源类库可以选择,比如AForge,OpenCV等等;WPF则可以使用WPFMediaKit(也可以通过WindowsFormsHost来使用WinForm的控件,但是效率肯定不如WinForm高,另外在此不得不高度评价下WPFMediaKit,用金老师的话来说,完美!)。

另外,对于透明通道的支持,WinForm简直让人无语啊,为什么会自动以父级的背景作为背景?当你把Picture控件叠加在摄像头控件上,你会惊喜的发现,这是什么鬼!当然,你可以使用强大的GDI来解决,不过那么多的毛边和刺刺是肿么回事!然后不得不再次感叹,WPF,完美!

虽然很多人拿WPF的效率说事,但是,在土豪客户面前,这些都不是事儿嘛!CPU上I7,内存搞个16G,显卡来个GTX9xx系列!能用钱解决的事情,那都不是事儿,当然,对我们这个初级的AR播放器来说,2GHz以上,4核的CPU就够用了;内存2G有点压力,4G应该足以应付,显卡嘛,集成显卡应该也没问题。

2、动画

2-1、Thread/Task/BackgroundWorker/Timer

使用WinForm的童鞋,首先想到的应该是这几个玩意儿了,不过除了BackgroundWorker以外,需要跨线程操作UI,简单介绍两种方法:

Control.CheckForIllegalCrossThreadCalls=false;//不检查线程冲突,虽然可以操作UI了,但是可能会产生难以预料的后果

Control.Invoke(委托,参数)//使用委托,需要刷新的控件Invoke一下

当然,WPF也可以使用,不过UI操作是酱紫滴:

Dispatcher.BeginInvoke(()=>{//做你该做的事情!});

2-2、DispatcherTimer/CompositionTarget

不得不说,WPF有许多好用的玩意儿,用起来可比WinForm舒服的多!

简单上一段代码:

 var timer=new DispatcherTimer();
timer.Interval=TimeSpan.FromMilliseconds(/);// fps:25/s
var sources=new List<BitmapImage>();//加载序列帧图片,省略代码
var index=; timer.Tick+=(s,e)=>
{
image.Source=sources[index++];//Image控件,叠加在摄像头控件之上 if(index>sources.Count-)
{
index=;
}
}; timer.Start();
//使用MediaPlayer播放音乐

其中:timer.Interval = TimeSpan.FromMilliseconds(1000 / 25);

因为渲染图片需要一定时间,图片大小不同,耗时不同,所以实际上达不到25帧每秒,很难与声音同步!

至于CompositionTarget.Rendering,是UI线程的回调,帧率固定为60/s(Silverlight倒是可以设置帧率),有可能阻塞UI线程,导致画面卡顿,还是不用为妙,当然,这玩意儿在某些场景还是很好用的!

2-3、Animation

终于到了Animation出场的时候,上代码:

var ani=new Int32Anitiation(,images.Count,TimeSpan.FromMilliseconds(images.Count * 1000.0 / fps));
//设置帧率
Timeline.SetDesiredFrameRate(ani, fps);
ani.CurrentTimeInvalidated +=(s,e)=>
{
//更新图片
img.Source=new BitmapImage(new Uri(images[ImageIndex]));
}; this.BeginAnimation(ImageIndexProperty, ani);

使用Animation会出现掉帧、跳帧的情况,例如由1直接变为3,又或者连续几个3,这样保证了总的时长不变,帧率也就相对稳定,也就可以与音频同步。

而使用DispatcherTimer,比如有600帧,希望的帧率为30(也就是一秒30张图片),理论总时长为600/30=20 (s),音频文件按此时长来制作,Interval=1000/30 -常量(Tick事件的耗时),在耗时较大情况下(图片文件较大,设备性能不行等原因),此值接近0甚至小于0,所以根本无法到达要求的帧率,实际总时长将大于理论时长,也就无法与音频同步!

AR播放器的更多相关文章

  1. 小菜学习Winform(二)WMPLib实现音乐播放器

    前言 现在网上有很多的音乐播放器,但好像都不是.net平台做的,在.net中实现音乐文件的播放功能很简单,下面就简单实现下. SoundPlayer类 在.net提供了音乐文件的类:SoundPlay ...

  2. OK6410移植madplay播放器,王明学learn

    对于ok6410的madplay移植主要包括三部分.声卡驱动移植,播放器的移植,以及alsa库的移植. 一.首先移植声卡驱动以及播放器 ok6410采用WM97系列的声卡芯片,要使得内核支持该驱动,首 ...

  3. HTML5实践之歌词同步播放器

    歌曲播放我们会发现他的兼容性不是很好,譬如IE上能播放的flash播放器,再firfox或者chrome上就不是很好的应用了,因为有插件的阻碍!HTML5的出现让这一切成为了可能,但是播放器虽然播放了 ...

  4. ios开发学习- 简易音乐播放器2 (基于iPhone4s屏幕尺寸)-- 歌词解析--plist文件应用--imageNamed图片加载耗内存

    声明:(部分图片来自网络,如果侵犯了您的权益请联系我,会尽快删除!) 又是音乐播放器,不过这次和上次不一样了,准确说这次更像播放器了,初学者不建议看这个,可以先看前面一个音乐播放器(1),当然 我没加 ...

  5. 使用react native制作的一款网络音乐播放器

    使用react native制作的一款网络音乐播放器 基于第三方库 react-native-video设计"react-native-video": "^1.0.0&q ...

  6. [Linux][Madplay播放器移植mini2440(ARM9)]

    Madplay移植到mini2440全过程详解 madplay交叉编译 交叉编译器:arm-linux-gcc 3.4.1PC环境:RedHat-6 注意:最好在root权限下执行以下移植,否则在ma ...

  7. 实现PC视频播放最强画质教程( Potplayer播放器+MADVR插件)【转】

    转自:http://www.hangge.com/blog/cache/detail_1461.html 一.MADVR介绍 MADVR 是一款超强的视频插件,其配合高清播放软件,可以做到目前 PC  ...

  8. iOS开发手记-仿QQ音乐播放器动态歌词的实现

    最近朋友想做个音乐App,让我帮忙参考下.其中歌词动态滚动的效果,正好我之前也没做过,顺便学习一下,先来个预览效果. 实现思路 歌词常见的就是lrc歌词了,我们这里也是通过解析lrc歌词文件来获取其播 ...

  9. HTML5播放器 MediaElement.js 使用方法

    目前已经有很多html5播放器可以使用,使用html5播放器可以轻松的在页面中插入媒体视频,从而使我们的web页面变得更加丰富多彩,所以今 天向大家推荐一款非常优秀的html5播放器MediaElem ...

随机推荐

  1. 论Top与ROW_NUMBER读取第一页的效率问题

    10.29 前一段时间研究关于分页的问题,由于数据库属于百万级的,考虑了关于优化方面的问题.其中一个考虑是:第一页展现的频率肯定是最高的,所以我想第一页就使用Top N来读取. 这个想法本身是没有错, ...

  2. Qt 怎么添加图片文件?

    1.新建一个.qrc的文件 2.起个.qrc的文件名 3.完成后,添加图片文件 4.如图 就好了.

  3. PADS_AD_Cadence转换

    PADS_AD_Cadence转换 软件版本:PADS的版本是PADS9.5,Altium designer的版本是Altium designer winter 09 PADS和AD的转换 PADS的 ...

  4. SmartPointer Smar指针

    #include<iostream> using namespace std; // private class for use by HasPtr only class U_Ptr { ...

  5. Javascript笔记----实现Page页面右下角置顶按钮.

    从用博客开始,发现博客园中很多博友的博客中在Page右下角都有个图标,不论屏幕怎么拉伸,都始终停留在右下角.点击后页面置顶.后面想想写一个Demo来实现这种效果吧. 一. 图标右下角固定. 1.SS ...

  6. ComboBox的联动

    窗体搭建: 实现功能: 加载年级下拉框 选中年级时加载出科目下拉框 加载年级下拉框: 第一步,在DAL层中写一个方法,检索所有的年级名称集合,返回的是泛型集合List<> public L ...

  7. 为什么使用Sass

    为什么使用Sass 作为前端(html.javascript.css)的三大马车之一的css,一直以静态语言存在,HTML5火遍大江南北了.javascript由于NODE.JS而成为目前前后端统一开 ...

  8. python-数据类型补充及文件处理操作

    ___数据类型____ 一.列表的复制 浅复制和深复制 浅复制只复制一层,深复制完全克隆,慎用 1.实现浅复制的三种方式: name=['song','xiao','nan'] import copy ...

  9. 逗号分隔的字符串转换为行数据(collection)

    逗号分隔的字符串转换为行数据(collection) CREATE OR REPLACE FUNCTION "GET_STR_TAB" (v_str in varchar2) re ...

  10. proxy改变this指向

    var core_slice = Array.prototype.slice; var proxy = function(context,fn) { var args, proxy; if ( typ ...