このエントリはOpenNI Advent Calendar 2011 : ATNDの12月4日分です!!
Advent Calendarでの、僕の全プロジェクトはこちらです
ちょっとWPFを触ったので、OpenNIでもWPFでやってみました。
とても簡単でびっくり。OpenNIのサンプルはWindows Formだけど、ライブラリはWPF用に作られているのではないかと思うほど...
見た目の解説
Imageを一つ貼り付けます。今度は、ツールボックスが出た。
<Window x:Class="CameraImageWPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="519" Width="663" Closing="Window_Closing"> <Grid> <Image Height="480" HorizontalAlignment="Left" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="640 " /> </Grid> </Window>
中身の解説
using System.Windows; using System.Windows.Media; using OpenNI; using System.Threading; using System.Windows.Media.Imaging; using System; using System.Windows.Threading; namespace CameraImageWPF { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { Context context; ImageGenerator image; private Thread readerThread; private bool shouldRun; public MainWindow() { InitializeComponent(); try { // ContextとImageGeneratorの作成 ScriptNode node; context = Context.CreateFromXmlFile( "SamplesConfig.xml", out node ); context.GlobalMirror = false; image = context.FindExistingNode( NodeType.Image ) as ImageGenerator; // 画像更新のためのスレッドを作成 shouldRun = true; readerThread = new Thread( new ThreadStart( () => { while ( shouldRun ) { context.WaitAndUpdateAll(); ImageMetaData imageMD = image.GetMetaData(); // ImageMetaDataをBitmapSourceに変換する(unsafeにしなくてもOK!!) this.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action( () => { image1.Source = BitmapSource.Create( imageMD.XRes, imageMD.YRes, 96, 96, PixelFormats.Bgr24, null, imageMD.ImageMapPtr, imageMD.DataSize, imageMD.XRes * imageMD.BytesPerPixel ); } ) ); } } ) ); readerThread.Start(); } catch ( Exception ex ) { MessageBox.Show( ex.Message ); } } private void Window_Closing( object sender, System.ComponentModel.CancelEventArgs e ) { shouldRun = false; } } }
初期化
特に変わらず
// ContextとImageGeneratorの作成 ScriptNode node; context = Context.CreateFromXmlFile( "SamplesConfig.xml", out node ); context.GlobalMirror = false; image = context.FindExistingNode( NodeType.Image ) as ImageGenerator;
データの更新
スレッドの作成までは同じ。BitmapSource.Createが、IntPtrとデータサイズを受け入れてくれるため、ImageMetaDataの内容で更新が可能です。
// 画像更新のためのスレッドを作成 shouldRun = true; readerThread = new Thread( new ThreadStart( () => { while ( shouldRun ) { context.WaitAndUpdateAll(); ImageMetaData imageMD = image.GetMetaData(); // ImageMetaDataをBitmapSourceに変換する(unsafeにしなくてもOK!!) this.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action( () => { image1.Source = BitmapSource.Create( imageMD.XRes, imageMD.YRes, 96, 96, PixelFormats.Bgr24, null, imageMD.ImageMapPtr, imageMD.DataSize, imageMD.XRes * imageMD.BytesPerPixel ); } ) ); } } ) ); readerThread.Start();