您的位置:首页 > 其它

AR播放器

2015-07-09 17:48 253 查看
一、项目需求

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 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,所以根本无法到达要求的帧率,实际总时长将大于理论时长,也就无法与音频同步!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: