zoukankan      html  css  js  c++  java
  • 加强版照片捕获

        在过去的十年中手机集成的相机逐渐取代传统口袋中的相机。

        开发一个提供先进拍照和图片处理的应用程序取决于两个方面 手机硬件和系统平台提供的照片捕获

    API。诺基亚的新的系列设备与新的 Windows Phone8 先进的照片捕获 API 为你提供能够调节拍照

    设备各种参数的权限,比如曝光时间、ISO、焦点位置和白平衡。

        引用一个扩展演示示例应用程序,本文描述了如何初始化和使用相机,如何读取参数,该设备支持的问题

    ,如何设置参数,以及如何捕获和存储照片。

       

         Windows Phone 8 增强的照片捕获 API

         WP8 发布了全新的照片捕获 API,包含了可以高度配置相机参数。新的相机特性主要包括下面:

    —获得或调整支持的相机参数:  

    static CameraCapturePropertyRange SupportedPropertyRange(CameraSensorLocation sensor, Guid propertyId)
    static IReadOnlyList<object> GetSupportedPropertyValues(CameraSensorLocation sensor, Guid propertyId)
    object GetProperty(Guid propertyId)
    void SetProperty(Guid propertyId, object value)


    —调用自动对焦,自动白平衡,自动曝光:

    static bool IsFocusSupported(CameraSensorLocation sensor)
    static bool IsFocusRegionSupported(CameraSensorLocation sensor)
    IAsyncOperation<CameraFocusStatus> FocusAsync()
    IAsyncOperation<CameraFocusStatus> ResetFocusAsync()


    —检查、设置预览、拍摄的分辨率

    static IReadOnlyList<Size> GetAvailablePreviewResolutions()
    static IReadOnlyList<Size> GetAvailableCaptureResolutions()
    IAsyncAction SetPreviewResolutionAsync(Size value)
    IAsyncAction SetCaptureResolutionAsync(Size value)


    —读取预览缓冲区:

    event TypedEventHandler<ICameraCaptureDevice, Object> PreviewFrameAvailable
    void GetPreviewBufferArgb(out int[] pixels)
    void GetPreviewBufferY(out byte[] pixels)
    void GetPreviewBufferYCbCr(out byte[] pixels)


    —创建捕获序列,然后用来捕捉帧:

    CameraCaptureSequence CreateCaptureSequence(uint numberOfFrames)
    IAsyncAction PrepareCaptureSequenceAsync(CameraCaptureSequence sequence)


        获取相机参数主要基于三种不同的方式。预览、读取捕获的分辨率和通过专门的同步方法设置。

    同样对焦的操作 API 中也有相应的特定方法。图像特定参数的调整依赖于方法中标注参数的 GUID,

    来声明参数值所支持的范围,和方法设置所支持的值。

        图像拍照指定的参数取值一般都是范围值或者既定的数组值,比如 ISO,指定在一个最大值和一个

    最小值,在这之间的值都是合法的。数组类型的参数由可能的值的列表组成,特别是设备上合法的枚举值。

        需要注意的是在应用中做上面的工作之前需要在清单文件  WMAppManifest.xml 中添加ID_CAP_ISV_CAMERA 权限声明。

    另外,保存图片到图片库需要添加

    ID_CAP_MEDIALIB_PHOTO。

    Nokia Lumia 相机参数

    下面的表格列出了 Lumia820 和 920 设备上与图片相关的主要的相机参数。                    

      

    设备

      
      

    Nokia Lumia 820

      
      

    Nokia Lumia 920

      
      

    摄像头

      
      

    Front

      
      

    Back

      
      

    Front

      
      

    Back

      

    自动对焦范围

    Infinity

    Auto, Macro, Normal, Full, Hyperfocal, Infinity

    Infinity

    Auto, Macro, Normal, Full, Hyperfocal, Infinity

    预览分辨率

    640x480

    800x448, 640x480

    1280x720, 1024x768

    1280x720, 1024x768

    捕获分辨率

    640x480

    3264x2448, 3552x2000, 2592x1936, 2592x1456, 2048x1536,   640x480

    1280x960, 1280x720, 640x480

    3264x2448, 3552x2000, 2592x1936, 2592x1456, 2048x1536,   640x480

    曝光补偿 (EV)

    -12...12

    -12...12

    -12...12

    -12...12

    曝光时间 (microseconds)

    1...33333

    1...500000

    1...33333

    1...500000

    Flash mode

    Off

    Auto, On, Off

    Off

    Auto, On, Off

    光照对焦模式

    Off

    Auto, On, Off

    Off

    Auto, On, Off

    ISO

    100...800

    100...800

    100...800

    100...800

    手动对焦位置

    No

    Yes, 1000 positions

    No

    Yes, 1000 positions

    场景模式

    Auto, Sport, Night, Backlit

    Auto, Macro, Sport, Night, Night Portrait, Backlit

    Auto, Sport, Night, Backlit

    Auto, Macro, Sport, Night, Night Portrait, Backlit

    预设白平衡

    Cloudy, Daylight, Fluorescent, Tungsten

    Cloudy, Daylight, Fluorescent, Tungsten

    Cloudy, Daylight, Fluorescent, Tungsten

    Camera Explorer application

    Camera Explorer 示例应用程序是关于 PhotoCaptureDevice 如何使用的部分示例。该应用程序包含一个实时

    取景器,一个包含很多调节参数的 settings 页面,和一个预览页面并且提供保存捕获图片的方法。

    Camera Explorer 工程的架构图:

       除了 4个主要的 Windows Phone application 页面,还有一个单例的 DataContext 对象包含应用程序里广泛

    使用的对象,比如一个 Settings 的实例和一个 PhotoCaptureDevice 的实例。

       DataContext 类在不同的页面中被使用:

    ...
    
    class DataContext : INotifyPropertyChanged
    {
        ...
    
        public static DataContext Singleton { ... }
    
        public ObservableCollection<Parameter> Parameters { ... }
    
        public PhotoCaptureDevice Device { ... }
    
        public MemoryStream ImageStream { ... }
    }

    捕获照片

    在 Mainpage 的 xaml 中使用一个 Canvas 元素作为取景框,使用一个 VideoBrush 作为背景画刷:

    <phone:PhoneApplicationPage x:Class="CameraExplorer.MainPage" ... >
        ...
    
        <Grid x:Name="LayoutRoot" ... >
            ...
    
            <Grid x:Name="ContentPanel" ... >
                <Canvas x:Name="VideoCanvas">
                    <Canvas.Background>
                        <VideoBrush x:Name="videoBrush"/>
                    </Canvas.Background>
                </Canvas>
    
                ...
            </Grid>
        </Grid>
    
        <phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar>
                <shell:ApplicationBarIconButton Text="capture" Click="captureButton_Click" ... />
         
                ...
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>
    
        ...
    </phone:PhoneApplicationPage>


    在 MainPage 的 C# 代码中,在InitializeCamera 方法中初始化 PhotoCaptureDevice 对象,并且被

    保存在 DataContext 中。在 XAML 中声明的捕获按钮事件中可以看到一个照片如何被捕获:

    ...
    
    public partial class MainPage : PhoneApplicationPage
    {
        private CameraExplorer.DataContext _dataContext = CameraExplorer.DataContext.Singleton;
    
        ...
    
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (_dataContext.Device == null)
            {
                ...
    
                await InitializeCamera(CameraSensorLocation.Back);
    
                ...
            }
    
            videoBrush.RelativeTransform = new CompositeTransform()
            {
                CenterX = 0.5,
                CenterY = 0.5,
                Rotation = _dataContext.Device.SensorLocation == CameraSensorLocation.Back ?
                           _dataContext.Device.SensorRotationInDegrees :
                         - _dataContext.Device.SensorRotationInDegrees
            };
    
            videoBrush.SetSource(_dataContext.Device);
    
            ...
        }
    
        private async Task InitializeCamera(CameraSensorLocation sensorLocation)
        {
            Windows.Foundation.Size initialResolution = new Windows.Foundation.Size(640, 480);
    
            PhotoCaptureDevice d = await PhotoCaptureDevice.OpenAsync(sensorLocation, initialResolution);
    
            d.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation,
                          d.SensorLocation == CameraSensorLocation.Back ?
                          d.SensorRotationInDegrees : -d.SensorRotationInDegrees);
    
            _dataContext.Device = d;
        }
    
        private async void captureButton_Click(object sender, EventArgs e)
        {
            if (!_manuallyFocused)
            {
                await AutoFocus();
            }
            await Capture();
        }
    
        private async Task AutoFocus()
        {
            if (!_capturing && PhotoCaptureDevice.IsFocusSupported(_dataContext.Device.SensorLocation))
            {
                ...
                await _dataContext.Device.FocusAsync();
                ...
                _capturing = false;
            }
        }
        
        private async Task Capture()
        {
            if (!_capturing)
            {
                _capturing = true;
                MemoryStream stream = new MemoryStream();
                CameraCaptureSequence sequence = _dataContext.Device.CreateCaptureSequence(1);
                sequence.Frames[0].CaptureStream = stream.AsOutputStream();
                await _dataContext.Device.PrepareCaptureSequenceAsync(sequence);
                await sequence.StartCaptureAsync();
                _dataContext.ImageStream = stream;
                ...
            }
            ...
        }
    
        ...
    }

    显示预览并且保存到 Camera roll

    显示一个捕获的照片的预览很容易。Camera Explorer 程序中使用一个 Image 的 XAML 元素使用一个

    BitmapImage 对象实现。另外,保存图片到 camera roll 也很容易。仅仅需要记住在

    MediaLibrary.SavePictureToCameraRoll(string name, Stream source) 方法中使用的图片流属性必须指定

    为图片数据的开始。

    <phone:PhoneApplicationPage x:Class="CameraExplorer.PreviewPage" ... >
        ...
    
        <Grid x:Name="LayoutRoot" ... >
            ...
    
            <Grid x:Name="ContentPanel" ... >
                <Image x:Name="image" Stretch="UniformToFill"/>
            </Grid>
        </Grid>
    
        <phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar>
                <shell:ApplicationBarIconButton Text="save" Click="saveButton_Click" ... />
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>
    
        ...
    </phone:PhoneApplicationPage>
    ...
    
    public partial class PreviewPage : PhoneApplicationPage
    {
        private CameraExplorer.DataContext _dataContext = CameraExplorer.DataContext.Singleton;
        private BitmapImage _bitmap = new BitmapImage();
    
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            ...
    
            _bitmap.SetSource(_dataContext.ImageStream);
    
            image.Source = _bitmap;
    
            ...
        }
    
        private void saveButton_Click(object sender, EventArgs e)
        {
            try
            {
                _dataContext.ImageStream.Position = 0;
    
                MediaLibrary library = new MediaLibrary();
    
                library.SavePictureToCameraRoll("CameraExplorer_" + DateTime.Now.ToString() + ".jpg",
                                                _dataContext.ImageStream);
            }
            catch (Exception)
            {
                ...
            }
    
            ...
        }
    }


    调整 Camera 的参数

    Camera Explorer 工程架构中的参数分不到  ArrayParameters 和RangeParameters 中,两者都继承自基类 Parameter。

    这种工程的参数架构提供一种简单并且可扩展的方式来处理参数并且把它们直接 绑定到屏幕中的 UI 控件,比如 ComboBox,

    Slider 和 Text。本文并没有涉及绑定,你可以参考程序的源码。

    下面是简化的 Parameter 基类:

    ...
    
    public abstract class Parameter : INotifyPropertyChanged
    {    
        ...
       
        protected Parameter(PhotoCaptureDevice device, string name)
        {
            ...
        }
     
        public PhotoCaptureDevice Device { ... }
    
        public string Name { ... }
    
        public bool Supported { ... }
    
        public abstract void Refresh();
    
        ...
    }

    上面只是 Wiki 的部分内容。

    NOKIA wiki 原文链接:http://developer.nokia.com/Resources/Library/Lumia/#!imaging/advanced-photo-capturing.html

  • 相关阅读:
    SAP ABAP 开发中常用的方法总结
    安装sap帮助文档
    spring成神之路第七篇:DI依赖注入之手动注入
    spring成神之路第三篇:Spring容器基本使用及原理(ApplicationContext接口获取bean的4种方式)
    spring成神之路第九篇:dependon到底是干什么的?
    spring成神之路第十篇:primary可以解决什么问题?
    spring成神之路第四篇:xml中bean定义详解
    spring成神之路第六篇:玩转bean scope,避免跳坑里
    spring成神之路第一篇:为何要学spring
    spring成神之路第五篇:创建bean实例的方式
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/3314633.html
Copyright © 2011-2022 走看看