一、项目需求
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舒服的多!
简单上一段代码:
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播放音乐