从第4版开始Silverlight支持摄像头和麦克风的使用,给网络多媒体展示提供了新的设计空间。

4-17是摄像头使用的示例

4-17中上方是1TextBlocktextblock1)文本控件,用于显示信息。左上方是1Rectanglerectangle)控件用于显示捕获的摄像头视频,右上方是1ListBox控件(listbox)用于显示截取的多张静态图像,右下方的Grid布局控件中是Imagep_w_picpath)控件用于显示当前截取的静态图片,4个按钮“启动摄像头”(button1)、“截取静态图”(button2)、“关闭摄像头”(button3)和“保存为JPG”(JPEG格式,button4)的Click事件的代码如下。

.xaml.cs文件的开始添加了引用:

using System.Windows.Media.Imaging;//for WriteableBitmap

using System.IO;//for Stream

同时定义了一些摄像头捕获动态图像使用的变量:

//定义摄像设备

    public VideoCaptureDevice camera;

    //创建捕获源对象

    public  CaptureSource capturesource = new CaptureSource();

    //创建视频刷

public VideoBrush videoBrush = new VideoBrush();

摄像头捕获动态图形的基本设计过程是:获取摄像设备—设置捕获源对象—设置视频刷—填充矩形显示。

4-17 摄像头使用示例

 
  1. “启动摄像头”:  
  2.  
  3. private void button1_Click(object sender, System.Windows.RoutedEventArgs e)  
  4.         {  
  5.             StartCamera();//摄像设备启动自定义程序  
  6.             //如果允许启用获取的摄像头            
  7.             if (CaptureDeviceConfiguration.RequestDeviceAccess())   
  8.              {   
  9.                capturesource.Start();//开始摄像  
  10.                 this.button2.IsEnabled=true;  
  11.                 this.button3.IsEnabled=true;  
  12.              }   
  13.         }  
  14.      其中StartCamera()的代码是:  
  15. private void StartCamera(){  
  16.             //检测摄像头  
  17.             VideoCaptureDevice cameradevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();  
  18.             //如果没有配置摄像头  
  19.             if (cameradevice == null){  
  20.                 this.textblock1.Text="没有可用的视频摄像头!";  
  21.                 this.button1.IsEnabled=false;  
  22.             }  
  23.             else{  
  24.             this.textblock1.Text="检测到摄像头:"+cameradevice.FriendlyName;  
  25.             //获取本机摄像头  
  26.             camera = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();   
  27.                 //设置捕获源对象设备为摄像头  
  28.                 capturesource.VideoCaptureDevice = camera;   
  29.                  //设置视频刷源  
  30.               videoBrush.SetSource(capturesource);  
  31.                 //利用视频刷填充矩形对象  
  32.                 this.rectangle.Fill = videoBrush;  
  33.             }  
  34.         }  
  35. “截取静态图”:  
  36. 这里仅仅是截取静态图形显示。  
  37. private void button2_Click(object sender, System.Windows.RoutedEventArgs e)  
  38.         {  
  39.             //截取静态图片及相应事件处理  
  40.             this.capturesource.CaptureImageAsync();  
  41.             this.capturesource.CaptureImageCompleted += (ss, se) => 
  42.                 {  
  43.                     if (se.Error == null)  
  44.                     {  
  45.                         this.p_w_picpath.Source = se.Result;                        
  46.                         WriteableBitmap bitmap =se.Result; //定义位图对象  
  47.                         Image p_w_picpath1 = new Image();  
  48.                         p_w_picpath1.Width=160;  
  49.                         p_w_picpath1.Stretch=Stretch.Fill;                          
  50.                         p_w_picpath1.Source=bitmap; //设置Image对象源,显示图形  
  51.                         this.listbox.Items.Add(p_w_picpath1);  
  52.                         this.button4.IsEnabled=true;  
  53.                     }  
  54.                     else{  
  55.                         this.textblock1.Text = se.Error.Message;  
  56.                         return;  
  57.                     }  
  58.                 };  
  59.         }  
  60. 其中this.capturesource.CaptureImageAsync()是启动截取源对象的方法,当截取完成时会自动执行this.capturesource.CaptureImageCompleted事件代码。  
  61. WriteableBitmap类提供了1个位图操作源,可以用于Image的显示源,也可以用于图形刷ImageBrush的图形源设置。  
  62. “保存为JPG”(JPEG格式):  
  63. 这里将显示在p_w_picpath中的图形保存为JPEG格式文件,文件名和路径是对话框选择的。  
  64. private void button4_Click(object sender, System.Windows.RoutedEventArgs e)  
  65.         {  
  66.             //创建对象,源来自iamge  
  67.             WriteableBitmap bitmap = new WriteableBitmap(p_w_picpath, null);  
  68.             //保存文件   
  69.             if (bitmap != null)  
  70.             {  
  71.                 SaveFileDialog saveJPEG = new SaveFileDialog();  
  72.                 saveJPEG.Filter = "JPEG Files (*.jpeg)|*.jpeg";  
  73.                 if (saveJPEG.ShowDialog().Value)  
  74.                 {  
  75.                     thisthis.textblock1.Text=this.textblock1.Text+" 保存文件:"+saveJPEG.SafeFileName;  
  76.                     using (Stream jpegstream = saveJPEG.OpenFile())  
  77.                     {  
  78.                         SaveToJPEGFile(bitmap, jpegstream);  
  79.                     }  
  80.                 }  
  81.             }  
  82.     }  
  83. 其中调用的SaveToJPEGFile(bitmap, jpegstream)方法中应用了1个网上下载的库函数“FJ.Core.dll”,其功能是可以对位图数据进行色彩、编码处理,变为JPEG格式,给程序设计提供了方便。这样,需要在客户端的项目“引用”中“添加引用”,选中“FJ.Core.dll”,实例中已经提供了这个库函数。感谢库函数的作者。  
  84. private static void SaveToJPEGFile(WriteableBitmap bitmap, Stream jpegstream)  
  85.          {                
  86.                 int width = bitmap.PixelWidth; //获取p_w_picpath信息  
  87.                 int height = bitmap.PixelHeight;  
  88.                 int unitrow = 3;  
  89.                 byte[][,] lattice = new byte[unitrow][,];  
  90.                 //建立图形区  
  91.                 for (int i = 0; i < unitrow; i++)  
  92.                 {  
  93.                   lattice [i] = new byte[width, height];  
  94.                 }  
  95.                 for (int row = 0; row < height; row++)  
  96.                 {  
  97.                     for (int column = 0; column < width; column++)  
  98.                     {  
  99.                         int pixel = bitmap.Pixels[width * row + column];  
  100.                         lattice [0][column, row] = (byte)(pixel >> 16);  
  101.                         lattice [1][column, row] = (byte)(pixel >> 8);  
  102.                         lattice [2][column, row] = (byte)pixel;  
  103.                     }  
  104.                 }  
  105.                 //应用FJ.Core.dll中的类处理,色彩处理  
  106.                 FluxJpeg.Core.ColorModel colormodel = new FluxJpeg.Core.ColorModel { colorspace = FluxJpeg.Core.ColorSpace.RGB };  
  107.                 FluxJpeg.Core.Image p_w_picpath2 = new FluxJpeg.Core.Image(colormodel, lattice);  
  108.                 MemoryStream stream = new MemoryStream();//将p_w_picpath2编码为JPEG  
  109.                 FluxJpeg.Core.Encoder.JpegEncoder jpegencoder = new FluxJpeg.Core.Encoder.JpegEncoder(p_w_picpath2, 100, stream);  
  110.                 jpegencoder.Encode();                     
  111.                 stream.Seek(0, SeekOrigin.Begin); //回到stream的初始位置                  
  112.                 byte[] buffer = new Byte[stream.Length]; //定义缓存区  
  113.                 //获取jpeg数据流,读入缓存  
  114.                 long bytesRead = stream.Read(buffer, 0, (int)stream.Length);                  
  115.                 jpegstream.Write(buffer, 0, buffer.Length); //写入文件流  
  116.      }   
  117.     “关闭摄像头”:  
  118. private void button3_Click(object sender, System.Windows.RoutedEventArgs e)  
  119.         {  
  120.             capturesource.Stop();   
  121.             this.rectangle.Fill=null;  
  122.             this.button2.IsEnabled=false;  
  123.             this.button3.IsEnabled=false;  
  124.             this.button4.IsEnabled=false;  
  125.         }