【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

时间: 2024-10-05 06:12:29

【WP开发】手电筒的相关文章

C#学习(九)之Windows Store App &amp; WP 开发小记(一)

由于课程已经讲述完毕,所以本次学习记录就讨论记录一下我在Windows Store App & WP开发中遇到的一些问题与收获. 一.数据库(Sqlite)的使用 虽然资料很难找,但sqlite在这两个平台的使用还是很简单的. 首先是环境配置阶段: 1.工具->拓展与更新->联机,然后在右上搜索sqlite,之后下载安装下图两个打勾的拓展包,注意要重启VS方才生效. 2.项目->管理NuGet程序包->联机,搜索sqlite,安装下图打勾内容,如果项目多出下图两个文件即安装

我的【学WP开发】应用开发历程

没有谁一开始就是开发大神,希望会从[学WP开发]应用摸索中成长,我会努力从新手小白蜕变成一名大神WP开发者,你,也可以! 先介绍一下我自己吧,我的微博昵称叫@ViiBoo-维柏,大家也可以叫我维柏,我是一名中专的学生,我对于WP开发者来说,也不过是一个小白而已,我学WP开发的时间很短,也就几个月的时间,甚至连C#的课程都没有学完,但我对于WP开发的热爱,导致于我的第一个应用[学WP开发]匆匆上线了. 刚开始的[学WP开发]的第一个版本说实话,真的很烂,虽然我只是一个开学C#的小白,但我第一次接触

wp开发之一,第二个异常

1.写了ToDoDataContext类,实现数据存储 在实例化类中,忘记检查 数据库 是否已存在,导致一直报错: "System.Data.SqlServerCe.SqlCeException"类型的未经处理的异常在 Microsoft.Phone.Interop.ni.dll 中发生 经过在ToDoDataContext 实现 CreateDatabase() 后数据保存可正常保存. 2.错误  无法将2类型"System.Data.Linq.Table<Table

Android开发----------- 手电筒改进版本

在之前的基础上 在 res 文件夹下面: 添加一个 drawable/local_me.xml localme_cml <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:drawable="@drawable/on" /> <!-- press

WP开发笔记——WP7 SDK使用技巧

俗话说的好,工欲善其事,必先利其器. 入门WP开发之前,免不了要先接触开发环境和开发工具.使用WP7 SDK进行开发,我们需要掌握SDK的一些实用技巧,以便我们的开发. 一.开启/关闭电脑键盘输入 WP7模拟器默认状态只能通过模拟出来的QWERTY键盘输入,用鼠标一个一个点太慢了. 这里介绍下开启/关闭电脑键盘输入的方法,详细操作步骤如下: 首先打开模拟器,在需要输入文字的地方点击鼠标,这时按下电脑键盘的PageUp键即可开启键盘输入,同时虚拟键盘将会自动关闭.如果需要关闭电脑键盘输入开启虚拟键

【WP开发学习笔记】之pivot控件

博主wp开发小白,学习中...欢迎交流,微博@马and康 pivot控件中文也称为枢纽,是wp系统中最常用的控件之一,几乎所有个软件多多少少都会运用这个控件,比如设置.日历等等:该控件可以实现页面左右的快速切换,运行也十分流畅.如在设置中通过左右滑动可以切换为应用程序.系统,日历中通过左右滑动可以切换年.月.日: 首先可以通过项目模板直接建立一个pivot应用程序,或者通过拖动工具箱中的pivot控件,当然也可以直接通过xaml代码来直接写出来,这一点就不多说了: 我在用pivot控件时遇到的第

【WP开发】加密篇:双向加密

说起双向加密,如果以前在.NET开发中弄过加/解密的朋友都不会陌生,常用的算法有DES.AES等.在RT应用程序中,也提供了加密相关的API,算法自然是一样的,只是API的封装方式不同罢了,因为RT不完全是托管代码,而又类似于COM的形式公开,这对于低端设备来说,性能可以提升,当然了,对于高端设备来说无所谓. 在WP的RT应用中,涉及到加/解密的API都在以下几个命名空间里,大家要用的就在里面找,也不是所有类都会用得上,加密一般就用两大类:需要恢复内容时选用双向加密,如DES.AES等算法:如果

关于 WP 开发中.xaml 与.xaml.cs 的关系

今天我们先来看一下在WP8.1开发中最长见到的几个文件之间的关系.比较论证,在看这个问题之前我们简单看看.NET平台其他两个不同的框架: Windows Forms 先看看Window Forms中的情况,下图为在VS中创建的默认Windows Forms项目结构: 分别回顾一下每个文件以及它们之间的关系: ┣━ Properties------------------------------------------- 项目属性文件夹 ┣━━━━━ AssemblyInfo.cs--------

WP开发之性能调试

对于WP7开发来说每个应用的性能调试很重要,在VS2010中提供了Windows Phone Performance Analysis这个小工具,类似Android平台下的TraceView可以查看整个应用的CPU占用.内存消耗和GC回收内存情况,对于图像显示的帧率也有记录,我们在VS2010的菜单栏中选择Debug下面的Start Windows Phone Performance Analysis即可启动,如图: 运行后会有两个选项,分别为在Performance Analysis Sett