zoukankan      html  css  js  c++  java
  • 【WP开发】手电筒

    或许很多人都想到,可以利用手机上摄像头的闪光灯做手电筒,当然,有利必有害,每次使用的时间不要过长,几分钟一般不会有什么问题,如果时间太长,难保会有损伤。

    以往的方案是调用视频录制功能来开始录制视频,同时打开摄像灯,就能做出手电筒了。

    其实啊,在8.1中,从RT库移植过来的MediaCapture类(位于Windows.Media.Capture命名空间)可以在不录制视频的时候打开摄像灯。

    也就是说,不需要调用StartRecordToXXX方法来开始录制,而是直接把摄像灯打开就行了,这样既不用写文件也不用消耗内存。大概思路我给大家说说。

    1、初始化MediaCapture组件,这一步肯定不能少的;

    2、MediaCapture类有一个VideoDeviceController属性,可以返回VideoDeviceController实例;

    3、返回的VideoDeviceController实例有一个TorchControl属性,可以返回一个TorchControl实例;

    4、TorchControl类有个Enabled属性,设置为true时,摄像灯就打开了,不必等开始录制它就会打开,如果设置为false,摄像灯就会关闭。

    聪明的你,一定明白了,对啊,就是这样。

    有人会问了,不是FlashControl吗,不是Flash是闪光灯,就是拍照片的时候闪一下那个,Flash只能闪一下,而手电筒是要持续亮着的,因此不能用Flash。

    好,有了原理,要实现就看动手了。

    这里我将初始化MediaCapture,清理MediaCapture,打开/关闭摄像灯等操作都封装起来。

        internal static class CaptureOperator
        {
            #region 私有字段
            static MediaCapture m_capture = null;
            static bool m_istorchOpened = false;
            static bool m_iscaptureCreated = false;
            #endregion
    
            #region 属性
            /// <summary>
            /// 指示摄像是否已打开
            /// </summary>
            public static bool IsTorchOpened
            {
                get { return m_istorchOpened; }
            }
            /// <summary>
            /// 指示MediaCapture是否已初始化
            /// </summary>
            public static bool IsCaptureCreated
            {
                get { return m_iscaptureCreated; }
            }
            #endregion
    
            #region 方法
            /// <summary>
            /// 初始化捕捉对象
            /// </summary>
            public async static Task CreateCaptureAsync ()
            {
                // 找出后置摄像头,一般闪光灯在后置摄像头上
                DeviceInformation backCapture = (from d in await GetCaptureDeviceseAsync() where d.EnclosureLocation.Panel == Panel.Back select d).FirstOrDefault();
    
                if (backCapture != null)
                {
                    MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();
                    settings.VideoDeviceId = backCapture.Id; //设备ID
                    settings.StreamingCaptureMode = StreamingCaptureMode.Video;
                    settings.PhotoCaptureSource = PhotoCaptureSource.Auto;
                    // 初始化
                    m_capture = new MediaCapture();
                    await m_capture.InitializeAsync(settings);
                    m_iscaptureCreated = true;
                }
            }
    
            /// <summary>
            /// 获取摄像头设备列表(前置,后置摄像头)
            /// </summary>
            /// <returns></returns>
            private async static Task<DeviceInformation[]> GetCaptureDeviceseAsync ()
            {
                var dvs = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
                return dvs.ToArray();
            }
    
            /// <summary>
            /// 清理捕捉对象
            /// </summary>
            /// <returns></returns>
            public static void CleanupCaptureAsync ()
            {
                if (m_capture != null)
                {
                    m_capture.Dispose();
                    m_capture = null;
                    m_iscaptureCreated = false;
                }
            }
    
            public static void OpenTorch ()
            {
                // 开闪光灯
                var vdcontrol = m_capture.VideoDeviceController.TorchControl;
                if (vdcontrol.Supported)
                {
                    vdcontrol.Enabled = true;
                    m_istorchOpened = true;
                }
            }
    
            public static void CloseTorch ()
            {
                // 关闭闪光灯
                var torch = m_capture.VideoDeviceController.TorchControl;
                if (torch.Supported)
                {
                    torch.Enabled = false;
                    m_istorchOpened = false;
                }
            }
    
    
            #endregion
        }

    其他的与前面我给大家分享过的“解决调用摄像头时死机”的代码一样,都是一个思路。重点是看:

                // 开摄像灯
                var vdcontrol = m_capture.VideoDeviceController.TorchControl;
                if (vdcontrol.Supported)
                {
                    vdcontrol.Enabled = true;
                    m_istorchOpened = true;
                }
    
                ……
                // 关闭摄像灯
                var torch = m_capture.VideoDeviceController.TorchControl;
                if (torch.Supported)
                {
                    torch.Enabled = false;
                    m_istorchOpened = false;
                }

    这才是手电筒的关键代码。

    另外一点,我前面也说过,在应用程序挂起或关闭时一定要把MediaCapture对象Dispose掉,不然系统资源被占用,会导致卡死。当应用程序继续运行重新初始化。

            public App()
            {
                this.InitializeComponent();
                this.Suspending += this.OnSuspending;
                this.Resuming += this.OnResuming;
                this.UnhandledException += App_UnhandledException;
            }
    
            void App_UnhandledException ( object sender, UnhandledExceptionEventArgs e )
            {
                System.Diagnostics.Debug.WriteLine(e.Exception.Message);
                CaptureOperator.CleanupCaptureAsync();
            }
    
            private async void OnResuming ( object sender, object e )
            {
                await CaptureOperator.CreateCaptureAsync();
            }
            private void OnSuspending(object sender, SuspendingEventArgs e)
            {
                var deferral = e.SuspendingOperation.GetDeferral();
    
                // TODO: 保存应用程序状态并停止任何后台活动
                CaptureOperator.CleanupCaptureAsync();
                deferral.Complete();
            }

    示例代码下载:http://files.cnblogs.com/tcjiaan/FlashlightApp.zip

  • 相关阅读:
    svn cleanup failed–previous operation has not finished 解决方法
    开源SNS社区系统推荐
    从网络获取图片本地保存
    MS SQL Server 数据库连接字符串
    KeepAlive
    Configure Git in debian
    sqlserver query time
    RPi Text to Speech (Speech Synthesis)
    SQL Joins with C# LINQ
    search or reseed identity columns in sqlserver 2008
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/4034474.html
Copyright © 2011-2022 走看看