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

  • 相关阅读:
    mysql删除重复记录,保存Id最小的一条
    前段时间,接手一个项目使用的是原始的jdbc作为数据库的访问,发布到服务器上在运行了一段时间之后总是会出现无法访问的情况,登录到服务器,查看tomcat日志发现总是报如下的错误。    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected est
    Mysql 插入中文错误:Incorrect string value: 'xE7xA8x8BxE5xBAx8F...' for column 'course' at row 1
    Data truncation: Out of range value for column 'Quality' at row 1
    tomcat部署时war和war exploded区别
    IDEA 在某个工程下一个module如何使用另一个module中的资源文件(.xml .prop等)
    MyBatis错误:Result Maps collection already contains value for novel.storage.mapper.NovelMapper.BaseResultMap
    compareTo返回值为-1 、 1 、 0 的排序问题
    深入理解JVM+G1+GC.pdf (中文版带书签)
    轻量级微服务架构(下册)(中文版带书签)、原书代码、数据集
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/4034474.html
Copyright © 2011-2022 走看看