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
    [源码下载]

  • 相关阅读:
    hi.baidu.com 百度流量统计
    Autofac is designed to track and dispose of resources for you.
    IIS Manager could not load type for module provider 'SharedConfig' that is declared in administration.config
    How to create and manage configuration backups in Internet Information Services 7.0
    定制swagger的UI
    NSwag在asp.net web api中的使用,基于Global.asax
    NSwag Tutorial: Integrate the NSwag toolchain into your ASP.NET Web API project
    JS变量对象详解
    JS执行上下文(执行环境)详细图解
    JS内存空间详细图解
  • 原文地址:https://www.cnblogs.com/webabcd/p/2635698.html
Copyright © 2011-2022 走看看