• 【WP 8.1开发】解决摄像头翻转问题(RuntimeApp篇)


    昨天,我非常马虎地给大家说了有关处理物理摄像头翻转的话题,今天,还是这个话题,而且内容不差,只是为了完整性,顺便也提供了运行时API的版本,其实实现起来与SL框架版本差不多,毕竟这两个框架都有不少API是共享的。

    首先,打开清单文件,在“应用程序”选项卡上,把“支持的旋转”右面的横向选上,其他的不要选,只选横向

    然后切换到“功能”选项卡,把 网络摄像机 和 图片库 勾上,因为我们要用到它们。

    同样,使用MediaCapture类时要注意,在应用程序挂起时把它释放掉,而在应用程序启动或继续运行时,对其进行初始化。

    在App类中加入以下代码:

            /// <summary>
            /// 视频捕捉对象
            /// </summary>
            public MediaCapture TheCapture { get; private set; }
    
            /// <summary>
            /// 初始化摄像头
            /// </summary>
            private async Task InitializeCapture ()
            {
                TheCapture = new MediaCapture();
                // 查找后置摄像头
                var deviceCollection = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
                DeviceInformation backCamera = deviceCollection.FirstOrDefault(d => d.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
                if (backCamera != null)
                {
                    MediaCaptureInitializationSettings setting = new MediaCaptureInitializationSettings();
                    setting.AudioDeviceId = "";
                    setting.VideoDeviceId = backCamera.Id;
                    await TheCapture.InitializeAsync(setting);
                }
                else
                {
                    await TheCapture.InitializeAsync();
                }
            }
    
            /// <summary>
            /// 清理摄像头相关资源
            /// </summary>
            private void CleanupCapture ()
            {
                if (TheCapture != null)
                {
                    TheCapture.Dispose();
                    TheCapture = null;
                }
            }

    InitializeCapture方法用来初始化捕捉组件,CleanupCapture方法则用来清理。InitializeCapture方法使用了Task,表示它可以异步等待,因为稍后要在Launch中调用,在导航到主页前调用,如果不进行异步等待的话,应用程序会在MediaCapture未初始化之前就进入了主页,而在主页中开启预览就会发生异常,因此,通过异步等待,可以确保在进入主页前完成MediaCapture对象的初始化。

    在OnLaunched方法中加入以下代码来初始化捕捉组件。

            protected async override void OnLaunched(LaunchActivatedEventArgs e)
            {
                // 隐藏状态栏
                Windows.UI.ViewManagement.StatusBar statusbar =
                    Windows.UI.ViewManagement.StatusBar.GetForCurrentView();
                await statusbar.HideAsync();
    #if DEBUG
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    this.DebugSettings.EnableFrameRateCounter = true;
                }
    #endif
    
                await this.InitializeCapture();
         ……

    使用StatusBar类是为了把系统栏隐藏起来,系统图标栏就是手机顶部那条图标栏,显示信号、时间等信息的地方。

    在应用程序挂起时,要释放MediaCapture对象,故要处理Suspending事件。

            private async void OnSuspending(object sender, SuspendingEventArgs e)
            {
                var deferral = e.SuspendingOperation.GetDeferral();
    
                // TODO: 保存应用程序状态并停止任何后台活动
    
                // 停止拍摄预览
                await TheCapture.StopPreviewAsync();
                this.CleanupCapture();
    
                deferral.Complete();
            }

    当应用程序从挂起(如切换到其他应用,或回到开始屏幕)状态中恢复时(回到应用程序),会引发Resuming事件,处理该事件并重新初始化MediaCapture对象。

            async void OnResuming ( object sender, object e )
            {
                await this.InitializeCapture();
                Frame root = Window.Current.Content as Frame;
                if (root != null)
                {
                    MainPage page = root.Content as MainPage;
                    if (page != null)
                        await page.SetCaptureSourceAsync();
                }
            }

    SetCaptureSourceAsync方法是在MainPage页面类中定义的一个方法,作用是获取MediaCapture对象的引用,并开始拍摄预览。方法的定义如下:

            public async System.Threading.Tasks.Task SetCaptureSourceAsync ()
            {
                capture = (App.Current as App).TheCapture;
                ce.Source = capture;
                await capture.StartPreviewAsync();
            }

    在Silverlight框架中,是通过VideoBrush来显示摄像头的预览画面的,而在运行时API中,从RT应用程序中移植了CaptureElement类,该类有一个Source属性,用于设置关联的MediaCapture实例,这样就可以在CaptureElement可视化元素中看到摄像头的预览效果了,接着调用StartPreviewAsync方法开始预览。

    拍照和保存照片的方法和前面的示例差不多,不过,运行时API可以使用Windows.Storage中的类来进行文件处理。

    通过以下代码获得图片库文件夹的引用:

    StorageFolder picDir = KnownFolders.PicturesLibrary;

    其他流程和前面的示例一样,先把照片捕捉到流中,再通过解码/编码的方法来调整图片的旋转方向。不过,这里还要提及一个细节:

    下面是示例的下载地址:http://files.cnblogs.com/tcjiaan/CameraRTTestApp.zip

  • 相关阅读:
    Oracle 组件 系列 小结
    Oracle Data Mining 组件 说明
    GIS空间索引(有了思路代码还不是手到擒来)
    完成端口与高性能服务器程序开发(转)
    const? const ! 全解
    服务器架构
    SDL 源码分析(2)
    数据结构个算法学习笔记(2)
    高性能服务器架构 的几个注意点 (HighPerformance Server Architecture)
    GIS底层开发总结
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/3946266.html
Copyright © 2020-2023  润新知