AR播放器

1、项目需求ide

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

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

 

2、解决方案this

一、WinForm仍是WPF?spa

关于摄像头操做,WinForm有不少开源类库能够选择,好比AForge,OpenCV等等;WPF则可使用WPFMediaKit(也能够经过WindowsFormsHost来使用WinForm的控件,可是效率确定不如WinForm高,另外在此不得不高度评价下WPFMediaKit,用金老师的话来讲,完美!)。线程

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

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

 

二、动画blog

2-一、Thread/Task/BackgroundWorker/Timer事件

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

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

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

 

固然,WPF也可使用,不过UI操做是酱紫滴:

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

 

2-二、DispatcherTimer/CompositionTarget

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

简单上一段代码:

 1 var timer=new DispatcherTimer();
 2 timer.Interval=TimeSpan.FromMilliseconds(1000/25);// fps:25/s 
 3 var sources=new List<BitmapImage>();//加载序列帧图片,省略代码
 4 var index=0;
 5 
 6 timer.Tick+=(s,e)=>
 7 {
 8    image.Source=sources[index++];//Image控件,叠加在摄像头控件之上
 9 
10    if(index>sources.Count-1)
11   {
12      index=0; 
13   }
14 };
15 
16 timer.Start();
17 //使用MediaPlayer播放音乐
View Code

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

由于渲染图片须要必定时间,图片大小不一样,耗时不一样,因此实际上达不到25帧每秒,很难与声音同步!


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

 

2-三、Animation

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

var ani=new Int32Anitiation(0,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);
View Code

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

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

相关文章
相关标签/搜索