zoukankan      html  css  js  c++  java
  • 与众不同 windows phone (21) Device(设备)之摄像头(拍摄照片, 录制视频)

    [索引页]
    [源码下载]


    与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频)



    作者:webabcd


    介绍
    与众不同 windows phone 7.5 (sdk 7.1) 之设备

    • 用摄像头拍摄照片
    • 用摄像头录制视频



    示例
    1、演示如何使用摄像头拍摄照片
    ImageDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Device.Camera.ImageDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Landscape" Orientation="Landscape"
        mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="800"
        shell:SystemTray.IsVisible="False">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <StackPanel Orientation="Horizontal">
                    <Canvas Width="320" Height="240">
                        <Canvas.Background>
                            <VideoBrush x:Name="videoBrush" />
                        </Canvas.Background>
                    </Canvas>
    
                    <!--显示拍摄到的图片-->
                    <Image Name="imgCapture" Width="320" Height="240" Margin="20 0 0 0" />
                    <!--显示拍摄到的图片的缩略图-->
                    <Image Name="imgCaptureThumbnail" Width="32" Height="24" Margin="20 0 0 0" />
                </StackPanel>
    
                <StackPanel Orientation="Horizontal">
                    <Button x:Name="btnShutter" Content="快门" Click="btnShutter_Click" />
                    <Button x:Name="btnFlash" Content="闪光灯" Click="btnFlash_Click" />
                    <Button x:Name="btnResolution" Content="分辨率" Click="btnResolution_Click" />
                </StackPanel>
    
                <TextBlock Name="lblMsg" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    ImageDemo.xaml.cs

    /*
     * 演示如何使用摄像头拍摄照片
     * 
     * PhotoCamera - 用于提供相机功能
     *     CameraType - 摄像头的类型(Microsoft.Devices.CameraType 枚举)
     *         Primary - 主摄像头
     *         FrontFacing - 前置摄像头
     *     AvailableResolutions - 获取摄像头的可用分辨率集合(返回一个 IEnumerable<Size> 类型的对象)
     *     FlashMode - 相机的闪光灯模式(Microsoft.Devices.FlashMode 枚举)
     *         On - 启用闪光灯
     *         Off - 禁用闪光灯
     *         Auto - 自动闪光灯
     *         RedEyeReduction - 消除红眼闪光灯
     *     Resolution - 相机的分辨率
     *     Orientation - 取景器与相机传感器对齐所需要顺时针旋转的度数(只读)
     *     
     *     CaptureImage() - 拍摄相机当前捕获到的照片
     *     IsFlashModeSupported(FlashMode mode) - 相机是否支持指定的闪光灯模式
     *     
     *     Initialized - 相机初始化时触发的事件(事件参数为 CameraOperationCompletedEventArgs 类型)
     *     CaptureStarted - 相机开始捕获图片时触发的事件
     *     CaptureCompleted - 相机捕获图片完成时触发的事件(事件参数为 CameraOperationCompletedEventArgs 类型)
     *     CaptureImageAvailable - 获得了捕获到的图片时触发的事件(事件参数为 ContentReadyEventArgs 类型)
     *     CaptureThumbnailAvailable - 获得了捕获到的图片的缩略图时触发的事件(事件参数为 ContentReadyEventArgs 类型)
     *     
     * 
     * CameraOperationCompletedEventArgs
     *     Succeeded - 操作是否成功
     *     Exception - 异常信息
     *     
     * 
     * ContentReadyEventArgs
     *     ImageStream - 获取到的图像流 
     *     
     * 
     * 注:如果要求只使用前置摄像头的话,则在 manifest 中添加 <Capability Name="ID_HW_FRONTCAMERA"/>
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using Microsoft.Devices;
    using System.IO;
    using System.IO.IsolatedStorage;
    using Microsoft.Xna.Framework.Media;
    using System.Windows.Navigation;
    using System.Windows.Media.Imaging;
    
    namespace Demo.Device.Camera
    {
        public partial class ImageDemo : PhoneApplicationPage
        {
            private PhotoCamera _camera;
    
            // 当前使用的摄像头分辨率在摄像头支持的分辨率集合中的索引
            private int _currentResolutionIndex = 0;
    
            public ImageDemo()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 设备是否支持主摄像头
                if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary))
                {
                    // 获取主摄像头,并注册相关事件
                    _camera = new PhotoCamera(CameraType.Primary);
                    _camera.Initialized += _camera_Initialized;
                    _camera.CaptureStarted += _camera_CaptureStarted;
                    _camera.CaptureCompleted += _camera_CaptureCompleted;
                    _camera.CaptureImageAvailable += _camera_CaptureImageAvailable;
                    _camera.CaptureThumbnailAvailable += _camera_CaptureThumbnailAvailable;
    
                    // 在 VideoBrush 上显示摄像头捕获到的实时信息
                    videoBrush.SetSource(_camera);
    
                    lblMsg.Text = "设备的主摄像头正在工作";
                }
                else
                {
                    lblMsg.Text = "此设备没有主摄像头";
    
                    btnShutter.IsEnabled = false;
                    btnFlash.IsEnabled = false;
                    btnResolution.IsEnabled = false;
                }
            }
    
            protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
            {
                // 释放相关资源
                if (_camera != null)
                {
                    _camera.Dispose();
    
                    _camera.Initialized -= _camera_Initialized;
                    _camera.CaptureStarted -= _camera_CaptureStarted;
                    _camera.CaptureCompleted -= _camera_CaptureCompleted;
                    _camera.CaptureImageAvailable -= _camera_CaptureImageAvailable;
                    _camera.CaptureThumbnailAvailable -= _camera_CaptureThumbnailAvailable;
                }
            }
    
            void _camera_Initialized(object sender, CameraOperationCompletedEventArgs e)
            {
                if (e.Succeeded)
                {
                    this.Dispatcher.BeginInvoke(delegate()
                    {
                        // 初始化闪光灯模式
                        _camera.FlashMode = FlashMode.Off;
                        btnFlash.Content = "闪光灯:Off";
    
                        // 初始化分辨率设置
                        _camera.Resolution = _camera.AvailableResolutions.ElementAt<Size>(_currentResolutionIndex);
                        btnResolution.Content = "分辨率:" + _camera.AvailableResolutions.ElementAt<Size>(_currentResolutionIndex);
    
                        lblMsg.Text = "主摄像头初始化成功";
                    });
                }
            }
    
            void _camera_CaptureStarted(object sender, EventArgs e)
            {
                // 开始捕获
                this.Dispatcher.BeginInvoke(delegate()
                {
                    lblMsg.Text = "图片开始捕获";
                });
            }
    
            void _camera_CaptureCompleted(object sender, CameraOperationCompletedEventArgs e)
            {
                // 拍照完成
                this.Dispatcher.BeginInvoke(delegate()
                {
                    lblMsg.Text = "图片捕获完成";
                });
            }
    
            void _camera_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
            {
                // 获得了所拍摄的图片
                this.Dispatcher.BeginInvoke(delegate()
                {
                    var bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(e.ImageStream);
    
                    imgCapture.Source = bitmapImage;
                });
            }
    
            public void _camera_CaptureThumbnailAvailable(object sender, ContentReadyEventArgs e)
            {
                // 获得了所拍摄的图片的缩略图
                this.Dispatcher.BeginInvoke(delegate()
                {
                    var bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(e.ImageStream);
    
                    imgCaptureThumbnail.Source = bitmapImage;
                });
            }
    
            private void btnShutter_Click(object sender, RoutedEventArgs e)
            {
                if (_camera != null)
                {
                    try
                    {
                        // 拍摄摄像头当前捕获的图片
                        _camera.CaptureImage();
                    }
                    catch (Exception ex)
                    {
                        lblMsg.Text = "拍摄失败:" + ex.Message;
                    }
                }
            }
    
            // 摄像头分辨率的轮换
            private void btnResolution_Click(object sender, RoutedEventArgs e)
            {
                if (++_currentResolutionIndex >= _camera.AvailableResolutions.Count())
                    _currentResolutionIndex = 0;
    
                _camera.Resolution = _camera.AvailableResolutions.ElementAt<Size>(_currentResolutionIndex);
                btnResolution.Content = "分辨率:" + _camera.AvailableResolutions.ElementAt<Size>(_currentResolutionIndex);
            }
    
            // 闪光灯模式的轮换
            private void btnFlash_Click(object sender, RoutedEventArgs e)
            {
                switch (_camera.FlashMode)
                {
                    case FlashMode.Off:
                        if (_camera.IsFlashModeSupported(FlashMode.On))
                        {
                            _camera.FlashMode = FlashMode.On;
                            btnFlash.Content = "闪光灯:On";
                        }
                        break;
                    case FlashMode.On:
                        if (_camera.IsFlashModeSupported(FlashMode.RedEyeReduction))
                        {
                            _camera.FlashMode = FlashMode.RedEyeReduction;
                            btnFlash.Content = "闪光灯:RedEyeReduction";
                        }
                        else if (_camera.IsFlashModeSupported(FlashMode.Auto))
                        {
                            _camera.FlashMode = FlashMode.Auto;
                            btnFlash.Content = "闪光灯:Auto";
                        }
                        else
                        {
                            _camera.FlashMode = FlashMode.Off;
                            btnFlash.Content = "闪光灯:Off";
                        }
                        break;
                    case FlashMode.RedEyeReduction:
                        if (_camera.IsFlashModeSupported(FlashMode.Auto))
                        {
                            _camera.FlashMode = FlashMode.Auto;
                            btnFlash.Content = "闪光灯:Auto";
                        }
                        else
                        {
                            _camera.FlashMode = FlashMode.Off;
                            btnFlash.Content = "闪光灯:Off";
                        }
                        break;
                    case FlashMode.Auto:
                        if (_camera.IsFlashModeSupported(FlashMode.Off))
                        {
                            _camera.FlashMode = FlashMode.Off;
                            btnFlash.Content = "闪光灯:Off";
                        }
                        break;
                }
            }
        }
    }


    2、演示如何使用摄像头录制视频
    VideoDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Device.Camera.VideoDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Landscape" Orientation="Landscape"
        mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="800"
        shell:SystemTray.IsVisible="False">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <StackPanel Orientation="Horizontal">
                    <!--用于实时显示摄像头捕获到的信息-->
                    <Canvas Width="320" Height="240">
                        <Canvas.Background>
                            <VideoBrush x:Name="videoBrush" />
                        </Canvas.Background>
                    </Canvas>
    
                    <!--用于播放视频-->
                    <MediaElement x:Name="mediaElement" Width="320" Height="240" />
                </StackPanel>
    
                <StackPanel Orientation="Horizontal">
                    <Button x:Name="btnStartRecord" Content="开始录制" Click="btnStartRecord_Click" />
                    <Button x:Name="btnStopRecord" Content="停止录制" Click="btnStopRecord_Click" />
                    <Button x:Name="btnStartPlayback" Content="开始播放" Click="btnStartPlayback_Click" />
                    <Button x:Name="btnPausePlayback" Content="暂停播放" Click="btnPausePlayback_Click" />
                </StackPanel>
    
                <TextBlock Name="lblMsg" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    VideoDemo.xaml.cs

    /*
     * 演示如何通过摄像头录制视频并保存到独立存储,以及如何播放独立存储中的视频
     * 
     * CaptureSource - 操作相关捕获设备的类
     *     VideoCaptureDevice - 关联的视频捕获设备(System.Windows.Media.VideoCaptureDevice 类型)
     *     AudioCaptureDevice - 关联的音频捕获设备(System.Windows.Media.AudioCaptureDevice 类型)
     *     State - 捕获的相关状态(System.Windows.Media.CaptureState 枚举)
     *         Stopped, Started, Failed
     *     Start() - 启动关联的视频捕获设备和音频捕获设备
     *     Stop() - 关闭关联的视频捕获设备和音频捕获设备
     *     CaptureImageAsync() - 异步捕获图像
     *     CaptureImageCompleted - 异步捕获图像完成后所触发的事件
     *     CaptureFailed - 捕获失败时所触发的事件
     * 
     * 
     * FileSink - 用于将捕获到的视频保存到独立存储的类
     *     CaptureSource - 关联的 CaptureSource 对象
     *     IsolatedStorageFileName - 需要保存到的独立存储的地址
     * 
     * 
     * CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice() - 获取默认的视频捕获设备,返回一个 VideoCaptureDevice 对象
     * CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices() - 获取可用的视频捕获设备集合,返回一个 VideoCaptureDevice 对象集合
     * CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice() - 获取默认的音频捕获设备,返回一个 AudioCaptureDevice 对象
     * CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices() - 获取可用的音频捕获设备集合,返回一个 AudioCaptureDevice 对象集合
     * 
     * 
     * VideoCaptureDevice - 用于描述视频捕获设备的类
     *     DesiredFormat - 期望的视频格式
     *     SupportedFormats - 支持的视频格式
     *     FriendlyName - 设备的名称
     *     IsDefaultDevice - 是否是视频捕获的默认设备
     *     
     * 
     * AudioCaptureDevice - 用于描述音频捕获设备的类
     *     AudioFrameSize - 音频的帧大小(缓冲大小),10 毫秒 - 2000 毫秒之间,默认值是 1000 毫秒
     *     DesiredFormat - 期望的音频格式
     *     SupportedFormats - 支持的音频格式
     *     FriendlyName - 设备的名称
     *     IsDefaultDevice - 是否是音频捕获的默认设备
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using System.Windows.Navigation;
    using System.IO.IsolatedStorage;
    using System.IO;
    
    namespace Demo.Device.Camera
    {
        public partial class VideoDemo : PhoneApplicationPage
        {
            private CaptureSource _captureSource;
            private FileSink _fileSink;
    
            // 保存到独立存储的视频的地址
            private string _isoVideoFileName = "myVideo.mp4";
            // 需要播放的独立存储中的视频文件的视频流
            private IsolatedStorageFileStream _isoVideoFile;
     
            public VideoDemo()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
                
                if (_captureSource == null)
                {
                    _captureSource = new CaptureSource();
                    _captureSource.CaptureFailed += _captureSource_CaptureFailed;
    
                    _fileSink = new FileSink();
    
                    VideoCaptureDevice videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
                    if (videoCaptureDevice == null)
                    {
                        lblMsg.Text = "该设备不支持视频捕获";
                    }
                    else
                    {
                        // 让 VideoBrush 显示视频捕获的实时信息
                        videoBrush.SetSource(_captureSource);
                        // 调用了 CaptureSource.Start() 之后才会开始捕获视频
                        _captureSource.Start();
    
                        lblMsg.Text = "设备正在捕获视频中。。。";
                    }
                }
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 垃圾回收
                DisposeVideoPlayer();
                DisposeVideoRecorder();
    
                base.OnNavigatedFrom(e);
            }
    
            private void _captureSource_CaptureFailed(object sender, ExceptionRoutedEventArgs e)
            {
                this.Dispatcher.BeginInvoke(delegate()
                {
                    lblMsg.Text = "视频捕获失败:" + e.ToString();
                });
            }
    
            public void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
            {
                // 视频播放完成后,重播
                mediaElement.Position = TimeSpan.Zero;
                mediaElement.Play();
            }
    
            // 清理视频播放的相关资源
            private void DisposeVideoPlayer()
            {
                // 注:对于那些没有实现 Dispose() 方法的对象,就把他们设置为 null,这样垃圾收集器会在需要的时候回收这些对象占用的内存
                
                mediaElement.Stop();
                mediaElement.MediaEnded -= mediaElement_MediaEnded;
                mediaElement.Source = null;
    
                _isoVideoFile = null;
            }
    
            // 清理视频录制的相关资源
            private void DisposeVideoRecorder()
            {
                // 注:对于那些没有实现 Dispose() 方法的对象,就把他们设置为 null,这样垃圾收集器会在需要的时候回收这些对象占用的内存
    
                if (_captureSource != null)
                {
                    if (_captureSource.VideoCaptureDevice != null && _captureSource.State == CaptureState.Started)
                        _captureSource.Stop();
    
                    _captureSource.CaptureFailed -= _captureSource_CaptureFailed;
                    _captureSource = null;
    
                    _fileSink = null;
                }
            }
    
            // 录制捕获到的视频
            private void btnStartRecord_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    // 清除视频播放的相关资源,因为系统无法同时录制视频和播放视频(也无法同时播放两个视频)
                    DisposeVideoPlayer();
    
                    if (_captureSource.VideoCaptureDevice != null && _captureSource.State == CaptureState.Started)
                    {
                        _captureSource.Stop();
    
                        // 将 FileSink 与 CaptureSource 做关联
                        _fileSink.CaptureSource = _captureSource;
                        // 设置录制好的视频所需保存到的独立存储的地址
                        _fileSink.IsolatedStorageFileName = _isoVideoFileName;
                    }
    
                    if (_captureSource.VideoCaptureDevice != null && _captureSource.State == CaptureState.Stopped)
                    {
                        // 开始捕获,如果关联了 FileSink,则会将捕获到的视频流以流的方式写入到指定的独立存储地址
                        _captureSource.Start();
                    }
    
                    lblMsg.Text = "开始录制视频";
                }
                catch (Exception ex)
                {
                    lblMsg.Text = "开始录制视频失败:" + ex.ToString();
                }
            }
    
            // 停止录制
            private void btnStopRecord_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    if (_captureSource.VideoCaptureDevice != null && _captureSource.State == CaptureState.Started)
                    {
                        _captureSource.Stop();
    
                        // 清空 FileSink 的相关联信息
                        _fileSink.CaptureSource = null;
                        _fileSink.IsolatedStorageFileName = null;
                    }
    
                    lblMsg.Text = "停止录制视频";
                }
                catch (Exception ex)
                {
                    lblMsg.Text = "停止录制视频失败:" + ex.ToString();
                }
            }
    
            // 播放视频
            private void btnStartPlayback_Click(object sender, RoutedEventArgs e)
            {
                if (_isoVideoFile != null)
                {
                    mediaElement.Play();
                }
                else
                {
                    // 停止视频捕获,因为系统无法同时录制视频和播放视频(也无法同时播放两个视频)
                    _captureSource.Stop();
    
                    _isoVideoFile = new IsolatedStorageFileStream(_isoVideoFileName, FileMode.Open, FileAccess.Read, IsolatedStorageFile.GetUserStoreForApplication());
    
                    // 用 MediaElement 播放独立存储中的指定视频
                    mediaElement.SetSource(_isoVideoFile);
                    mediaElement.MediaEnded += mediaElement_MediaEnded;
                    mediaElement.Play();
                }
    
                lblMsg.Text = "开始播放视频";
            }
    
            // 暂停播放视频
            private void btnPausePlayback_Click(object sender, RoutedEventArgs e)
            {
                mediaElement.Pause();
    
                lblMsg.Text = "暂停播放视频";
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    python爬虫 js逆向之取巧秒解webpack打包的加密参数
    程序员半夜泡奶粉,睡不着了
    擴展Membership建立中小型WEB權限框架(一)
    Gridview小技巧保存選擇狀態
    sql server 2005行列轉換
    一个简单的WEB流程图组件[demo]
    web效率14條規則(轉)
    常用javascript 表達式驗證[綜合轉載]
    SOA、反射+緩存
    数据表的设计原则(轉載)
  • 原文地址:https://www.cnblogs.com/webabcd/p/2635698.html
Copyright © 2011-2022 走看看