Controles de cámara manuales en Xamarin. iOSManual Camera Controls in Xamarin.iOS

Los controles de cámara manuales, proporcionados por el AVFoundation Framework en iOS 8, permiten que una aplicación móvil tenga control total sobre la cámara de un dispositivo iOS.The Manual Camera Controls, provided by the AVFoundation Framework in iOS 8, allow a mobile application to take full control over an iOS device's camera. Este nivel específico de control se puede usar para crear aplicaciones de cámara de nivel profesional y proporcionar composiciones de artista mediante el ajuste de los parámetros de la cámara mientras se toma una imagen o un vídeo.This fine-grained level of control can be used to create professional level camera applications and provide artist compositions by tweaking the parameters of the camera while taking a still image or video.

Estos controles también pueden ser útiles a la hora de desarrollar aplicaciones científicas o industriales, donde los resultados están menos orientados hacia la corrección o la belleza de la imagen, y están orientados más hacia el resaltado de alguna característica o elemento de la imagen que se está llevando a cabo.These controls can also be useful when developing scientific or industrial applications, where the results are less geared towards the correctness or beauty of the image, and are geared more towards highlighting some feature or element of the image being taken.

Objetos de captura AVFoundationAVFoundation Capture Objects

Tanto si se toman vídeo como imágenes fijas mediante la cámara en un dispositivo iOS, el proceso usado para capturar esas imágenes es en gran medida el mismo.Whether taking video or still images using the camera on an iOS device, the process used to capture those images is largely the same. Esto se aplica a las aplicaciones que usan los controles de cámara automatizados predeterminados o a los que aprovechan los nuevos controles de cámara manuales:This is true of applications that use the default automated camera controls or ones that take advantage of the new Manual Camera Controls:

La entrada se toma de una AVCaptureDeviceInput en un AVCaptureSession por medio de un AVCaptureConnection.Input is taken from an AVCaptureDeviceInput into an AVCaptureSession by way of an AVCaptureConnection. El resultado se genera como una imagen fija o como una secuencia de vídeo.The result is either output as a still image or as a video stream. Un AVCaptureDevicecontrola todo el proceso.The entire process is controlled by an AVCaptureDevice.

Controles manuales proporcionadosManual Controls Provided

Con las nuevas API proporcionadas por iOS 8, la aplicación puede tomar el control de las siguientes características de la cámara:Using the new APIs provided by iOS 8, the application can take control of the following camera features:

  • Enfoque manual : al permitir que el usuario final tome el control del foco directamente, una aplicación puede proporcionar más control sobre la imagen tomada.Manual Focus – By allowing the end user to take control of the focus directly, an application can provide more control over the image taken.
  • Exposición manual : al proporcionar control manual sobre la exposición, una aplicación puede proporcionar más libertad a los usuarios y permitirles obtener una apariencia estilizada.Manual Exposure – By providing manual control over the exposure, an application can provide more freedom to users and allow them to achieve a stylized look.
  • Balance manual en blanco : el balance de blanco se usa para ajustar el color de una imagen, a menudo para que parezca realista.Manual White Balance – White Balance is used to adjust the color in an image—often to make it look realistic. Diferentes fuentes de luz tienen temperaturas de color diferentes y la configuración de la cámara utilizada para capturar una imagen se ajusta para compensar estas diferencias.Different light sources have different color temperatures, and the camera settings used to capture an image is adjusted to compensate for these differences. De nuevo, al permitir el control de usuario sobre el equilibrio de blanco, los usuarios pueden realizar ajustes que no se pueden realizar automáticamente.Again, by allowing the user control over the white balance, users can make adjustments that cannot be done automatically.

iOS 8 proporciona extensiones y mejoras a las API de iOS existentes para proporcionar este control específico sobre el proceso de captura de imágenes.iOS 8 provides extensions and enhancements to existing iOS APIs to provide this fine-grained control over the image capture process.

Captura entre corchetesBracketed Capture

La captura entre corchetes se basa en la configuración de los controles de la cámara manual presentada anteriormente y permite a la aplicación capturar un momento dado, de varias maneras diferentes.The Bracketed Capture is based on the settings from the Manual Camera Controls presented above and allows the application to capture a moment in time, in a variety of different ways.

Simplemente se ha indicado que la captura entre corchetes es una ráfaga de imágenes fijas tomadas con una variedad de opciones de imagen a imagen.Simply stated, Bracketed Capture is a burst of still images taken with a variety of settings from picture to picture.

RequisitosRequirements

Para completar los pasos que se describen en este artículo, es necesario lo siguiente:The following are required to complete the steps presented in this article:

  • Xcode 7 + e iOS 8 o posterior : las API Xcode 7 e iOS 8 de Apple o las API más recientes deben estar instaladas y configuradas en el equipo del desarrollador.Xcode 7+ and iOS 8 or newer – Apple's Xcode 7 and iOS 8 or newer APIs need to be installed and configured on the developer's computer.
  • Visual Studio para Mac : la versión más reciente de Visual Studio para Mac debe estar instalada y configurada en el dispositivo del usuario.Visual Studio for Mac – The latest version of Visual Studio for Mac should be installed and configured on the user device.
  • dispositivo iOS 8 : un dispositivo iOS que ejecuta la versión más reciente de iOS 8.iOS 8 Device – An iOS device running the latest version of iOS 8. No se pueden probar las características de la cámara en el simulador de iOS.Camera features cannot be tested in the iOS Simulator.

Configuración de captura de AV generalGeneral AV Capture Setup

Al grabar vídeo en un dispositivo iOS, hay un código de configuración general que siempre es necesario.When recording video on an iOS device, there is some general setup code that is always required. En esta sección se tratará la configuración mínima necesaria para grabar vídeo desde la cámara del dispositivo iOS y mostrar ese vídeo en tiempo real en un UIImageView.This section will cover the minimal setup that is required to record video from the iOS device's camera and display that video in real-time in a UIImageView.

Delegado de búfer de ejemplo de salidaOutput Sample Buffer Delegate

Una de las primeras cosas necesarias será un delegado para supervisar el búfer de salida de ejemplo y mostrar una imagen capturada desde el búfer a un UIImageView en la interfaz de usuario de la aplicación.One of the first things needed will be a delegate to monitor the Sample Output buffer and display an image grabbed from the buffer to a UIImageView in the application UI.

La rutina siguiente supervisará el búfer de ejemplo y actualizará la interfaz de usuario:The following routine will monitor the Sample Buffer and update the UI:

using System;
using Foundation;
using UIKit;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using AVFoundation;
using CoreVideo;
using CoreMedia;
using CoreGraphics;

namespace ManualCameraControls
{
    public class OutputRecorder : AVCaptureVideoDataOutputSampleBufferDelegate
    {
        #region Computed Properties
        public UIImageView DisplayView { get; set; }
        #endregion

        #region Constructors
        public OutputRecorder ()
        {

        }
        #endregion

        #region Private Methods
        private UIImage GetImageFromSampleBuffer(CMSampleBuffer sampleBuffer) {

            // Get a pixel buffer from the sample buffer
            using (var pixelBuffer = sampleBuffer.GetImageBuffer () as CVPixelBuffer) {
                // Lock the base address
                pixelBuffer.Lock (0);

                // Prepare to decode buffer
                var flags = CGBitmapFlags.PremultipliedFirst | CGBitmapFlags.ByteOrder32Little;

                // Decode buffer - Create a new colorspace
                using (var cs = CGColorSpace.CreateDeviceRGB ()) {

                    // Create new context from buffer
                    using (var context = new CGBitmapContext (pixelBuffer.BaseAddress,
                        pixelBuffer.Width,
                        pixelBuffer.Height,
                        8,
                        pixelBuffer.BytesPerRow,
                        cs,
                        (CGImageAlphaInfo)flags)) {

                        // Get the image from the context
                        using (var cgImage = context.ToImage ()) {

                            // Unlock and return image
                            pixelBuffer.Unlock (0);
                            return UIImage.FromImage (cgImage);
                        }
                    }
                }
            }
        }
        #endregion

        #region Override Methods
        public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
        {
            // Trap all errors
            try {
                // Grab an image from the buffer
                var image = GetImageFromSampleBuffer(sampleBuffer);

                // Display the image
                if (DisplayView !=null) {
                    DisplayView.BeginInvokeOnMainThread(() => {
                        // Set the image
                        if (DisplayView.Image != null) DisplayView.Image.Dispose();
                        DisplayView.Image = image;

                        // Rotate image to the correct display orientation
                        DisplayView.Transform = CGAffineTransform.MakeRotation((float)Math.PI/2);
                    });
                }

                // IMPORTANT: You must release the buffer because AVFoundation has a fixed number
                // of buffers and will stop delivering frames if it runs out.
                sampleBuffer.Dispose();
            }
            catch(Exception e) {
                // Report error
                Console.WriteLine ("Error sampling buffer: {0}", e.Message);
            }
        }
        #endregion
    }
}

Una vez realizada esta rutina, el AppDelegate se puede modificar para abrir una sesión de captura de AV y grabar una fuente de vídeo en directo.With this routine in place, the AppDelegate can be modified to open an AV Capture Session to record a live video feed.

Creación de una sesión de captura de AVCreating an AV Capture Session

La sesión de captura de AV se usa para controlar la grabación de vídeo en directo desde la cámara del dispositivo iOS y es necesario para obtener el vídeo en una aplicación de iOS.The AV Capture session is used to control recording of live video from the iOS Device's camera and is required to get video into an iOS application. Dado que el ejemplo ManualCameraControl aplicación de ejemplo usa la sesión de captura en varios lugares distintos, se configurará en el AppDelegate y estará disponible para toda la aplicación.Since the example ManualCameraControl sample application is using the capture session in several different places, it will be configured in the AppDelegate and made available to the entire application.

Realice lo siguiente para modificar el AppDelegate de la aplicación y agregar el código necesario:Do the following to modify the application's AppDelegate and add the necessary code:

  1. Haga doble clic en el archivo AppDelegate.cs en el Explorador de soluciones para abrirlo para su edición.Double-click the AppDelegate.cs file in the Solution Explorer to open it for editing.

  2. Agregue las siguientes instrucciones using al principio del archivo:Add the following using statements to the top of the file:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    
  3. Agregue las siguientes variables privadas y propiedades calculadas a la clase AppDelegate:Add the following private variables and computed properties to the AppDelegate class:

    #region Private Variables
    private NSError Error;
    #endregion
    
    #region Computed Properties
    public override UIWindow Window {get;set;}
    public bool CameraAvailable { get; set; }
    public AVCaptureSession Session { get; set; }
    public AVCaptureDevice CaptureDevice { get; set; }
    public OutputRecorder Recorder { get; set; }
    public DispatchQueue Queue { get; set; }
    public AVCaptureDeviceInput Input { get; set; }
    #endregion
    
  4. Invalide el método terminado y cámbielo a:Override the finished method and change it to:

    public override void FinishedLaunching (UIApplication application)
    {
        // Create a new capture session
        Session = new AVCaptureSession ();
        Session.SessionPreset = AVCaptureSession.PresetMedium;
    
        // Create a device input
        CaptureDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video);
        if (CaptureDevice == null) {
            // Video capture not supported, abort
            Console.WriteLine ("Video recording not supported on this device");
            CameraAvailable = false;
            return;
        }
    
        // Prepare device for configuration
        CaptureDevice.LockForConfiguration (out Error);
        if (Error != null) {
            // There has been an issue, abort
            Console.WriteLine ("Error: {0}", Error.LocalizedDescription);
            CaptureDevice.UnlockForConfiguration ();
            return;
        }
    
        // Configure stream for 15 frames per second (fps)
        CaptureDevice.ActiveVideoMinFrameDuration = new CMTime (1, 15);
    
        // Unlock configuration
        CaptureDevice.UnlockForConfiguration ();
    
        // Get input from capture device
        Input = AVCaptureDeviceInput.FromDevice (CaptureDevice);
        if (Input == null) {
            // Error, report and abort
            Console.WriteLine ("Unable to gain input from capture device.");
            CameraAvailable = false;
            return;
        }
    
        // Attach input to session
        Session.AddInput (Input);
    
        // Create a new output
        var output = new AVCaptureVideoDataOutput ();
        var settings = new AVVideoSettingsUncompressed ();
        settings.PixelFormatType = CVPixelFormatType.CV32BGRA;
        output.WeakVideoSettings = settings.Dictionary;
    
        // Configure and attach to the output to the session
        Queue = new DispatchQueue ("ManCamQueue");
        Recorder = new OutputRecorder ();
        output.SetSampleBufferDelegate (Recorder, Queue);
        Session.AddOutput (output);
    
        // Let tabs know that a camera is available
        CameraAvailable = true;
    }
    
  5. Guarde los cambios en el archivo.Save the changes to the file.

Con este código en su lugar, los controles de cámara manuales se pueden implementar fácilmente para experimentar y probar.With this code in place, the Manual Camera Controls can be easily implemented for experimentation and testing.

Enfoque manualManual Focus

Al permitir que el usuario final tome controles del foco directamente, una aplicación puede proporcionar un control más artístico sobre la imagen tomada.By allowing the end user to take controls of the focus directly, an application can provide more artistic control over the image taken.

Por ejemplo, un fotógrafo profesional puede suavizar el foco de una imagen para lograr un efecto bokeh:For example, a professional photographer can soften the focus of an image to achieve a Bokeh Effect:

O bien, cree un efecto de extracción de foco, como:Or, create a Focus Pull Effect, such as:

En el caso de los científicos o de un escritor de aplicaciones médicas, es posible que la aplicación desee mover mediante programación la lente de los experimentos.For scientists or a writer of medical applications, the application might want to programmatically move the lens around for experiments. En cualquier caso, la nueva API permite que el usuario final o la aplicación tomen el control sobre el foco en el momento en que se toma la imagen.Either way the new API allows either the end user or the application to take control over focus at the time the image is taken.

Cómo funciona el focoHow Focus Works

Antes de analizar los detalles de cómo controlar el foco en una aplicación de IOS 8.Before discussing the details of controlling focus in an IOS 8 application. Echemos un vistazo rápido a cómo funciona el enfoque en un dispositivo iOS:Let's take a quick look at how focus works in an iOS device:

La luz entra en la lente de la cámara en el dispositivo iOS y se centra en un sensor de imagen.Light enters the camera lens on the iOS device and is focused on an image sensor. La distancia de la lente desde los controles del sensor donde se encuentra el punto focal (el área donde la imagen será la más nítida), en relación con el sensor.The distance of the lens from the sensor controls where the Focal Point (the area where the image will appear the sharpest) is, in relationship to the sensor. Cuanto más lejos sea el objetivo del sensor, los objetos de distancia parecen más nítidos y los objetos cercanos más cercanos parecen más nítidos.The farther the lens is from the sensor, distance objects seem sharpest and the closer, near objects seem sharpest.

En un dispositivo iOS, la lente se mueve más cerca o después del sensor por imanes y muelles.In an iOS device, the lens is moved closer to, or further from, the sensor by magnets and springs. Como resultado, no es posible el posicionamiento exacto de la lente, ya que variará de un dispositivo a otro y puede verse afectado por parámetros como la orientación del dispositivo o la edad del dispositivo y la primavera.As a result, exact positioning of the lens is impossible, as it will vary from device to device, and can be affected by parameters such as the orientation of the device or the age of the device and spring.

Términos de enfoque importantesImportant Focus Terms

Al trabajar con el foco, hay algunos términos con los que el desarrollador debe estar familiarizado:When dealing with focus, there are a few terms that the developer should be familiar with:

  • Profundidad de campo : la distancia entre los objetos enfocados más cercanos y más alejados.Depth of Field – The distance between the nearest and farthest in-focus objects.
  • Macro : es el extremo cercano del espectro de foco y es la distancia más cercana a la que se puede centrar la lente.Macro - This is the near end of the focus spectrum and is the closest distance at which the lens can focus.
  • Infinity : este es el extremo del espectro de foco y es la distancia más lejana a la que se puede centrar la lente.Infinity – This is the far end of the focus spectrum and is the farthest distance at which the lens can focus.
  • Distancia de hiperfocalización : este es el punto en el espectro de foco, donde el objeto más alejado del marco está justo al final del foco.Hyperfocal Distance – This is the point in the focus spectrum where the farthest object in the frame is just at the far end of focus. En otras palabras, esta es la posición focal que maximiza la profundidad del campo.In other words, this is the focal position that maximizes Depth of Field.
  • Posición del objetivo : es lo que controla todos los demás términos.Lens Position – That's what controls all of the above other terms. Es la distancia de la lente desde el sensor y, por tanto, el controlador de foco.This is the distance of the lens from the sensor and thereby the controller of focus.

Teniendo en cuenta estos términos y conocimientos, los nuevos controles de enfoque manual se pueden implementar correctamente en una aplicación de iOS 8.With these terms and knowledge in mind, the new Manual Focus Controls can be successfully implemented in an iOS 8 application.

Controles de foco existentesExisting Focus Controls

iOS 7 y versiones anteriores proporcionaban controles de enfoque existentes a través de FocusModepropiedad como:iOS 7, and earlier versions, provided existing Focus Controls via FocusModeproperty as:

  • AVCaptureFocusModeLocked: el foco está bloqueado en un único punto de enfoque.AVCaptureFocusModeLocked – The focus is locked at a single focus point.
  • AVCaptureFocusModeAutoFocus: la cámara barre la lente a través de todos los puntos focales hasta que encuentra un enfoque agudo y luego permanece allí.AVCaptureFocusModeAutoFocus – The camera sweeps the lens through all focal points until it finds sharp focus and then stays there.
  • AVCaptureFocusModeContinuousAutoFocus: la cámara se reenfoca cada vez que detecta una condición de desenfoque.AVCaptureFocusModeContinuousAutoFocus – The camera refocuses whenever it detects an out-of-focus condition.

Los controles existentes también proporcionan un punto de interés configurable a través de la propiedadFocusPointOfInterest, para que el usuario pueda centrarse en un área determinada.The existing controls also provided a settable point of interest via theFocusPointOfInterest property, so that the user can tap to focus on a particular area. La aplicación también puede realizar un seguimiento del movimiento de la lente supervisando la propiedad IsAdjustingFocus.The application can also track the lens movement by monitoring the IsAdjustingFocus property.

Además, la restricción de intervalo la proporcionó la propiedad AutoFocusRangeRestriction como:In addition, range restriction was provided by the AutoFocusRangeRestriction property as:

  • AVCaptureAutoFocusRangeRestrictionNear: restringe el foco a profundidades cercanas.AVCaptureAutoFocusRangeRestrictionNear – Restricts the autofocus to nearby depths. Útil en situaciones como el examen de un código QR o código de barras.Useful in situations such as scanning a QR Code or barcode.
  • AVCaptureAutoFocusRangeRestrictionFar: restringe el foco a profundidades distantes.AVCaptureAutoFocusRangeRestrictionFar – Restricts the autofocus to distant depths. Resulta útil en situaciones en las que los objetos que se sabe que son irrelevantes se encuentran en el campo de la vista (por ejemplo, un marco de ventana).Useful in situations where objects that are known to be irrelevant are in the field of view (for instance, a window frame).

Por último, hay la propiedad SmoothAutoFocus que reduce el algoritmo de enfoque automático y lo recorre en incrementos más pequeños para evitar mover los artefactos al grabar vídeo.Finally there is the SmoothAutoFocus property that slows down the auto focus algorithm and steps it in smaller increments to avoid moving artifacts when recording video.

Nuevos controles de enfoque en iOS 8New Focus Controls in iOS 8

Además de las características ya proporcionadas por iOS 7 y versiones posteriores, las siguientes características están ahora disponibles para controlar el foco en iOS 8:In addition to the features already provided by iOS 7 and above, the following features are now available to control focus in iOS 8:

  • Control manual completo de la posición del objetivo al bloquear el foco.Full manual control of the lens position when locking focus.
  • Observación de clave-valor de la posición del objetivo en cualquier modo de enfoque.Key-value observation of the lens position in any focus mode.

Para implementar las características anteriores, la clase AVCaptureDevice se ha modificado para incluir una propiedad de LensPosition de solo lectura que se usa para obtener la posición actual de la lente de la cámara.To implement the above features, the AVCaptureDevice class has been modified to include a read-only LensPosition property used to get the current position of the camera lens.

Para tomar el control manual de la posición de la lente, el dispositivo de captura debe estar en modo de enfoque bloqueado.To take manual control of the Lens Position, the Capture Device must be in the Locked Focus Mode. Ejemplo:Example:

CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;

El método SetFocusModeLocked del dispositivo de captura se usa para ajustar la posición de la lente de la cámara.The SetFocusModeLocked method of the Capture Device is used to adjust the position of the camera lens. Se puede proporcionar una rutina de devolución de llamada opcional para recibir una notificación cuando el cambio surta efecto.An optional callback routine can be provide to get notification when the change takes effect. Ejemplo:Example:

ThisApp.CaptureDevice.LockForConfiguration(out Error);
ThisApp.CaptureDevice.SetFocusModeLocked(Position.Value,null);
ThisApp.CaptureDevice.UnlockForConfiguration();

Tal como se ha mostrado en el código anterior, el dispositivo de captura debe estar bloqueado para la configuración antes de que se pueda realizar un cambio en la posición de la lente.As seen in the code above, the Capture Device must be locked for configuration before a change in Lens Position can be made. Los valores de posición de lente válidos están entre 0,0 y 1,0.Valid Lens Position values are between 0.0 and 1.0.

Ejemplo de enfoque manualManual Focus Example

Con el código de configuración de la captura de AV general en su lugar, se puede Agregar un UIViewController al guión gráfico de la aplicación y configurarlo de la manera siguiente:With the General AV Capture Setup code in place, a UIViewController can be added to the application's Storyboard and configured as follows:

La vista contiene los siguientes elementos principales:The view contains the following main elements:

  • UIImageView que mostrará la fuente de vídeo.A UIImageView that will display the video feed.
  • UISegmentedControl que cambiará el modo de enfoque de automático a bloqueado.A UISegmentedControl that will change the Focus Mode from Automatic to Locked.
  • UISlider que mostrará y actualizará la posición actual del objetivo.A UISlider that will show and update the current Lens Position.

Realice lo siguiente para conectar el controlador de vista para el control de foco manual:Do the following to wire-up the view controller for Manual Focus Control:

  1. Agregue las siguientes instrucciones Using:Add the following using statements:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Agregue las siguientes variables privadas:Add the following private variables:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Agregue las siguientes propiedades calculadas:Add the following computed properties:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Invalide el método ViewDidLoad y agregue el código siguiente:Override the ViewDidLoad method and add the following code:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Create a timer to monitor and update the UI
        SampleTimer = new Timer (5000);
        SampleTimer.Elapsed += (sender, e) => {
            // Update position slider
            Position.BeginInvokeOnMainThread(() =>{
                Position.Value = ThisApp.Input.Device.LensPosition;
            });
        };
    
        // Watch for value changes
        Segments.ValueChanged += (object sender, EventArgs e) => {
    
            // Lock device for change
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
    
            // Take action based on the segment selected
            switch(Segments.SelectedSegment) {
            case 0:
                // Activate auto focus and start monitoring position
                Position.Enabled = false;
                ThisApp.CaptureDevice.FocusMode = AVCaptureFocusMode.ContinuousAutoFocus;
                SampleTimer.Start();
                Automatic = true;
                break;
            case 1:
                // Stop auto focus and allow the user to control the camera
                SampleTimer.Stop();
                ThisApp.CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;
                Automatic = false;
                Position.Enabled = true;
                break;
            }
    
            // Unlock device
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        // Monitor position changes
        Position.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic) return;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.SetFocusModeLocked(Position.Value,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    }
    
  5. Invalide el método ViewDidAppear y agregue lo siguiente para iniciar la grabación cuando se cargue la vista:Override the ViewDidAppear method and add the following to start recording when the view loads:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
            SampleTimer.Start ();
        }
    }
    
  6. Con la cámara en el modo auto, el control deslizante se moverá automáticamente cuando la cámara ajuste el foco:With the camera in the Auto mode, the slider will move automatically as the camera adjusts focus:

  7. Puntee en el segmento bloqueado y arrastre el control deslizante posición para ajustar la posición del objetivo manualmente:Tap the Locked segment and drag the position slider to adjust the lens position manually:

  8. Detenga la aplicación.Stop the application.

En el código anterior se ha mostrado cómo supervisar la posición de la lente cuando la cámara está en modo automático o usar un control deslizante para controlar la posición de la lente cuando está en modo bloqueado.The above code has shown how to monitor the lens position when the camera is in the Automatic mode or use a slider to control the lens position when it is in the Locked mode.

Exposición manualManual Exposure

La exposición se refiere al brillo de una imagen en relación con el brillo del origen y se determina por la cantidad de luz que llega al sensor, durante cuánto tiempo y por el nivel de ganancia del sensor (asignación ISO).Exposure refers to the brightness of an image relative to the source brightness, and is determined by how much light hits the sensor, for how long, and by the gain-level of the sensor (ISO mapping). Al proporcionar un control manual sobre la exposición, una aplicación puede proporcionar más libertad al usuario final y permitirles obtener una apariencia estilizada.By providing manual control over the exposure, an application can provide more freedom to the end user and allow them to achieve a stylized look.

Mediante el uso de los controles de exposición manual, el usuario puede tomar una imagen de poco realista a oscuro y Moody:Using the Manual Exposure Controls, the user can take an image from unrealistically bright to dark and moody:

De nuevo, esto se puede hacer automáticamente mediante el control de programación para aplicaciones científicas o a través de controles manuales proporcionados por la interfaz de usuario de aplicaciones.Again, this can be done automatically using programmatic control for scientific applications or via manual controls provided by the applications user interface. En cualquier caso, las nuevas API de exposición de iOS 8 proporcionan un control exhaustivo sobre la configuración de exposición de la cámara.Either way, the new iOS 8 Exposure APIs provide fine-grained control over the camera's exposure settings.

Cómo funciona la exposiciónHow Exposure Works

Antes de analizar los detalles del control de la exposición en una aplicación de IOS 8.Before discussing the details of controlling exposure in an IOS 8 application. Echemos un vistazo rápido a cómo funciona la exposición:Let's take a quick look at how exposure works:

Los tres elementos básicos que se reúnen para controlar la exposición son:The three basic elements that come together to control exposure are:

  • Velocidad de obturación : es el período de tiempo que está abierto el obturador para que se ilumine en el sensor de cámara.Shutter Speed – This is the length of time that the shutter is open to let light onto the camera sensor. Cuanto más corta sea el obturador abierto, menos claro es dejar que la imagen sea más nítida (menos el desenfoque de movimiento).The shorter the time the shutter is open, the less light is let in and the crisper the image is (less motion blur). Cuanto más tiempo esté abierto el obturador, mayor será la luz y más desenfoque de movimiento que se produzca.The longer the shutter is open, the more light is let in and the more motion blur that occurs.
  • Asignación ISO : se trata de un término que se toma prestado de la fotografía de la película y hace referencia a la confidencialidad de los productos químicos de la película que se van a aclarar.ISO Mapping – This is a term borrowed from film photography and refers to the sensitivity of the chemicals in the film to light. Los valores ISO bajos de la película tienen menos grano y una reproducción de color más fina. los valores ISO bajos de los sensores digitales tienen menos ruido del sensor pero menos brillo.Low ISO values in film have less grain and finer color reproduction; low ISO values on digital sensors have less sensor noise but less brightness. Cuanto mayor sea el valor ISO, más brillante será la imagen, pero con más ruido de sensor.The higher the ISO value, the brighter the image but with more sensor noise. "ISO" en un sensor digital es una medida de ganancia electrónica, no de una característica física.“ISO” on a digital sensor is a measure of electronic gain, not a physical feature.
  • Abertura de lente : es el tamaño de la apertura de la lente.Lens Aperture – This is the size of the lens opening. En todos los dispositivos iOS, la abertura de la lente es fija, por lo que los únicos dos valores que se pueden usar para ajustar la exposición son la velocidad de obturación e ISO.On all iOS devices the lens aperture is fixed, so the only two values that can be used to adjust exposure are Shutter Speed and ISO.

Cómo funciona la exposición automática continuaHow Continuous Auto Exposure Works

Antes de aprender cómo funciona la exposición manual, es una buena idea comprender cómo funciona la exposición automática continua en un dispositivo iOS.Before learning how manual exposure works, it’s a good idea to understand how continuous auto exposure works in an iOS device.

En primer lugar, el bloque de exposición automática tiene el trabajo de calcular la exposición ideal y se está introduciendo continuamente estadísticas de medición. Utiliza esta información para calcular la mezcla óptima de ISO y la velocidad de obturación para conseguir que la escena esté bien iluminada.First is the Auto Exposure Block, it has the job of calculating ideal exposure and is continuously being fed Metering Stats. It uses this information to calculate the optimal mixture of ISO and Shutter Speed to get the scene well lit. Este ciclo se conoce como el bucle AE.This cycle is referred to as the AE Loop.

Cómo funciona la exposición bloqueadaHow Locked Exposure Works

A continuación, vamos a examinar cómo funciona la exposición bloqueada en dispositivos iOS.Next, let's examine how locked exposure works in iOS devices.

De nuevo, tiene el bloque de exposición automática que está intentando calcular los valores óptimos de iOS y Duration.Again, you have the Auto Exposure Block that is trying to calculate the optimal iOS and Duration values. Sin embargo, en este modo, el bloque AE está desconectado del motor de estadísticas de medición.However, in this mode the AE Block is disconnected from the Metering Stats engine.

Controles de exposición existentesExisting Exposure Controls

iOS 7 y versiones posteriores, proporcionan los siguientes controles de exposición existentes a través de la propiedad ExposureMode:iOS 7 and above, provide the following existing Exposure controls via the ExposureMode property:

  • AVCaptureExposureModeLocked: muestrea la escena una vez y usa esos valores a lo largo de la escena.AVCaptureExposureModeLocked – Samples the scene once and uses those values throughout the scene.
  • AVCaptureExposureModeContinuousAutoExposure: muestrea la escena continuamente para asegurarse de que está bien iluminada.AVCaptureExposureModeContinuousAutoExposure – Samples the scene continuously to ensure that it is well lit.

El ExposurePointOfInterest se puede usar para pulsar para exponer la escena seleccionando un objeto de destino en el que exponer y la aplicación puede supervisar la propiedad AdjustingExposure para ver cuándo se está ajustando la exposición.The ExposurePointOfInterest can be used to tap to expose the scene by selecting a target object to expose on, and the application can monitor the AdjustingExposure property to see when exposure is being adjusted.

Nuevos controles de exposición en iOS 8New Exposure Controls in iOS 8

Además de las características ya proporcionadas por iOS 7 y versiones posteriores, las siguientes características están ahora disponibles para controlar la exposición en iOS 8:In addition to the features already provided by iOS 7 and above, the following features are now available to control exposure in iOS 8:

  • Exposición personalizada totalmente manual.Fully manual custom exposure.
  • Get, Set y key-value ven la velocidad de IOS y obturador (duración).Get, Set and Key-Value Observe IOS and Shutter Speed (Duration).

Para implementar las características anteriores, se ha agregado un nuevo modo de AVCaptureExposureModeCustom.To implement the above features, a new AVCaptureExposureModeCustom mode has been added. Cuando la cámara en es el modo personalizado, se puede usar el siguiente código para ajustar la duración de la exposición e ISO:When the camera in is the custom mode, the following code can be used to adjust the Exposure Duration and ISO:

CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.LockExposure(DurationValue,ISOValue,null);
CaptureDevice.UnlockForConfiguration();

En los modos automático y bloqueado, la aplicación puede ajustar la diferencia de la rutina de exposición automática mediante el código siguiente:In the Auto and Locked modes, the application can adjust the Bias of the automatic exposure routine using the following code:

CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.SetExposureTargetBias(Value,null);
CaptureDevice.UnlockForConfiguration();

Los intervalos de configuración mínima y máxima dependen del dispositivo en el que se ejecuta la aplicación, por lo que nunca deben estar codificados de forma rígida.The minimum and maximum setting ranges depend on the device the application is running on, so they should never be hard coded. En su lugar, use las siguientes propiedades para obtener los intervalos de valores mínimo y máximo:Instead, use the following properties to get the minimum and maximum value ranges:

  • CaptureDevice.MinExposureTargetBias
  • CaptureDevice.MaxExposureTargetBias
  • CaptureDevice.ActiveFormat.MinISO
  • CaptureDevice.ActiveFormat.MaxISO
  • CaptureDevice.ActiveFormat.MinExposureDuration
  • CaptureDevice.ActiveFormat.MaxExposureDuration

Tal como se ha mostrado en el código anterior, el dispositivo de captura debe estar bloqueado para la configuración antes de que se pueda realizar un cambio de exposición.As seen in the code above, the Capture Device must be locked for configuration before a change in exposure can be made.

Ejemplo de exposición manualManual Exposure Example

Con el código de configuración de la captura de AV general en su lugar, se puede Agregar un UIViewController al guión gráfico de la aplicación y configurarlo de la manera siguiente:With the General AV Capture Setup code in place, a UIViewController can be added to the application's Storyboard and configured as follows:

La vista contiene los siguientes elementos principales:The view contains the following main elements:

  • UIImageView que mostrará la fuente de vídeo.A UIImageView that will display the video feed.
  • UISegmentedControl que cambiará el modo de enfoque de automático a bloqueado.A UISegmentedControl that will change the Focus Mode from Automatic to Locked.
  • Cuatro UISlider controles que mostrarán y actualizarán el desplazamiento, la duración, la ISO y la diferencia.Four UISlider controls that will show and update the Offset, Duration, ISO and Bias.

Realice lo siguiente para conectar el controlador de vista para el control de exposición manual:Do the following to wire-up the view controller for Manual Exposure Control:

  1. Agregue las siguientes instrucciones Using:Add the following using statements:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Agregue las siguientes variables privadas:Add the following private variables:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    private nfloat ExposureDurationPower = 5;
    private nfloat ExposureMinimumDuration = 1.0f/1000.0f;
    #endregion
    
  3. Agregue las siguientes propiedades calculadas:Add the following computed properties:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Invalide el método ViewDidLoad y agregue el código siguiente:Override the ViewDidLoad method and add the following code:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Set min and max values
        Offset.MinValue = ThisApp.CaptureDevice.MinExposureTargetBias;
        Offset.MaxValue = ThisApp.CaptureDevice.MaxExposureTargetBias;
    
        Duration.MinValue = 0.0f;
        Duration.MaxValue = 1.0f;
    
        ISO.MinValue = ThisApp.CaptureDevice.ActiveFormat.MinISO;
        ISO.MaxValue = ThisApp.CaptureDevice.ActiveFormat.MaxISO;
    
        Bias.MinValue = ThisApp.CaptureDevice.MinExposureTargetBias;
        Bias.MaxValue = ThisApp.CaptureDevice.MaxExposureTargetBias;
    
        // Create a timer to monitor and update the UI
        SampleTimer = new Timer (5000);
        SampleTimer.Elapsed += (sender, e) => {
            // Update position slider
            Offset.BeginInvokeOnMainThread(() =>{
                Offset.Value = ThisApp.Input.Device.ExposureTargetOffset;
            });
    
            Duration.BeginInvokeOnMainThread(() =>{
                var newDurationSeconds = CMTimeGetSeconds(ThisApp.Input.Device.ExposureDuration);
                var minDurationSeconds = Math.Max(CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MinExposureDuration), ExposureMinimumDuration);
                var maxDurationSeconds = CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MaxExposureDuration);
                var p = (newDurationSeconds - minDurationSeconds) / (maxDurationSeconds - minDurationSeconds);
                Duration.Value = (float)Math.Pow(p, 1.0f/ExposureDurationPower);
            });
    
            ISO.BeginInvokeOnMainThread(() => {
                ISO.Value = ThisApp.Input.Device.ISO;
            });
    
            Bias.BeginInvokeOnMainThread(() => {
                Bias.Value = ThisApp.Input.Device.ExposureTargetBias;
            });
        };
    
        // Watch for value changes
        Segments.ValueChanged += (object sender, EventArgs e) => {
    
            // Lock device for change
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
    
            // Take action based on the segment selected
            switch(Segments.SelectedSegment) {
            case 0:
                // Activate auto exposure and start monitoring position
                Duration.Enabled = false;
                ISO.Enabled = false;
                ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure;
                SampleTimer.Start();
                Automatic = true;
                break;
            case 1:
                // Lock exposure and allow the user to control the camera
                SampleTimer.Stop();
                ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.Locked;
                Automatic = false;
                Duration.Enabled = false;
                ISO.Enabled = false;
                break;
            case 2:
                // Custom exposure and allow the user to control the camera
                SampleTimer.Stop();
                ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.Custom;
                Automatic = false;
                Duration.Enabled = true;
                ISO.Enabled = true;
                break;
            }
    
            // Unlock device
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        // Monitor position changes
        Duration.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic) return;
    
            // Calculate value
            var p = Math.Pow(Duration.Value,ExposureDurationPower);
            var minDurationSeconds = Math.Max(CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MinExposureDuration),ExposureMinimumDuration);
            var maxDurationSeconds = CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MaxExposureDuration);
            var newDurationSeconds = p * (maxDurationSeconds - minDurationSeconds) +minDurationSeconds;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.LockExposure(CMTime.FromSeconds(p,1000*1000*1000),ThisApp.CaptureDevice.ISO,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        ISO.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic) return;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.LockExposure(ThisApp.CaptureDevice.ExposureDuration,ISO.Value,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        Bias.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            // if (Automatic) return;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.SetExposureTargetBias(Bias.Value,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    }
    
  5. Invalide el método ViewDidAppear y agregue lo siguiente para iniciar la grabación cuando se cargue la vista:Override the ViewDidAppear method and add the following to start recording when the view loads:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
            SampleTimer.Start ();
        }
    }
    
  6. Con la cámara en el modo auto, los controles deslizantes se mueven automáticamente cuando la cámara ajusta la exposición:With the camera in the Auto mode, the sliders will move automatically as the camera adjusts exposure:

  7. Puntee en el segmento bloqueado y arrastre el control deslizante de sesgo para ajustar la diferencia de la exposición automática manualmente:Tap the Locked segment and drag the Bias slider to adjust the bias of the automatic exposure manually:

  8. Puntee en el segmento personalizado y arrastre los controles deslizantes de duración e ISO para controlar manualmente la exposición:Tap the Custom segment and drag the Duration and ISO sliders to manually control exposure:

  9. Detenga la aplicación.Stop the application.

En el código anterior se ha mostrado cómo supervisar la configuración de exposición cuando la cámara está en modo automático y cómo usar los controles deslizantes para controlar la exposición cuando está en los modos bloqueado o personalizado.The above code has shown how to monitor the exposure settings when the camera is in the Automatic mode, and how to use sliders to control the exposure when it is in the Locked or Custom modes.

Balance manual de blancosManual White Balance

Los controles de balance de blanco permiten a los usuarios ajustar el equilibrio de colosr en una imagen para que tengan un aspecto más realista.White Balance controls allow users to adjust the balance of colosr in an image to make them look more realistic. Diferentes fuentes de luz tienen temperaturas de color diferentes y la configuración de la cámara utilizada para capturar una imagen debe ajustarse para compensar estas diferencias.Different light sources have different color temperatures, and the camera settings used to capture an image must be adjusted to compensate for these differences. De nuevo, al permitir el control del usuario sobre el balance de blanco, pueden realizarse ajustes profesionales en los que las rutinas automáticas no pueden conseguir efectos artísticos.Again, by allowing the user control over the white balance they can make professional adjustments that the automatic routines are incapable of to achieve artistic effects.

Por ejemplo, el horario de verano tiene una conversión azul, mientras que las luces incandescentes Tungsten tienen un matiz más cálido, naranja-naranja.For instance, daylight has a blueish cast, whereas tungsten incandescent lights have a warmer, yellow-orange tint. (Confuso, los colores "esporádicos" tienen temperaturas de color más altas que los colores "semiactivos".(Confusingly, “cool” colors have higher color temperatures than “warm” colors. Las temperaturas de color son una medida física, no una perceptual.Color temperatures are a physical measure, not a perceptual one.)

La mente humana es muy buena para compensar las diferencias en la temperatura del color, pero esto es algo que una cámara no puede hacer.The human mind is very good at compensating for the differences in color temperature, but this is something that a camera cannot do. La cámara funciona aumentando el color en el espectro opuesto para ajustarse a las diferencias de color.The camera works by boosting color on the opposite spectrum to adjust for the color differences.

La nueva API de exposición de iOS 8 permite que la aplicación tome el control del proceso y proporcione un control exhaustivo sobre la configuración de equilibrio de blancos de la cámara.The new iOS 8 Exposure API allows the application to take control of the process and provide fine-grained control over the camera's white balance settings.

Cómo funciona el equilibrio de blancosHow White Balance Works

Antes de analizar los detalles del control del equilibrio de blanco en una aplicación de IOS 8.Before discussing the details of controlling white balance in an IOS 8 application. Echemos un vistazo rápido a cómo funciona el equilibrio de blancos:Let's take a quick look at how white balance works:

En el estudio de la percepción de color, el espacio de colores de cie 1931 RGB y el espacio de colores cie 1931 XYZ son los primeros espacios de colores definidos matemáticamente.In the study of color perception, the CIE 1931 RGB color space and CIE 1931 XYZ color space are the first mathematically defined color spaces. Fueron creados por la Comisión Internacional en iluminación (CIE) en 1931.They were created by the International Commission on Illumination (CIE) in 1931.

En el gráfico anterior se muestran todos los colores visibles para el ojo humano, desde el azul profundo hasta el verde brillante hasta el rojo brillante.The above chart shows us all of the colors visible to the human eye, from deep blue to bright green to bright red. Cualquier punto del diagrama se puede trazar con un valor X e y, tal y como se muestra en el gráfico anterior.Any point on the diagram can be plotted with an X and Y value, as shown on the graph above.

Como se muestra en el gráfico, hay valores X e y que se pueden trazar en el gráfico que estarán fuera del intervalo de visión humana y, como resultado, estos colores no se pueden reproducir mediante una cámara.As visible in the graph, there are X and Y values that can be plotted on the graph that would be outside of the range of human vision, and as a result these colors cannot be reproduced by a camera.

La curva más pequeña del gráfico anterior se denomina Planckian raíz, que expresa la temperatura del color (en grados Kelvin), con números mayores en el lado azul (más cálido) y números inferiores en el lado rojo (refrigerado).The smaller curve in the above chart is called the Planckian Locus, which expresses the color temperature (in degrees kelvin), with higher numbers on the blue side (hotter) and lower numbers on the red side (cooler). Son útiles para las situaciones de iluminación típicas.These are useful for typical lighting situations.

En condiciones de iluminación mixta, los ajustes del balance de blanco deberán desviarse de la raíz de Planckian para realizar los cambios necesarios.In mixed lighting conditions, the white balance adjustments will need to deviate from the Planckian Locus to make the required changes. En estas situaciones, el ajuste tendrá que desplazarse al lado verde o rojo/magenta de la escala de CIE.In these situations the adjustment will need to be shifted either to the green or red/magenta side of the CIE scale.

los dispositivos iOS compensan las conversiones de color aumentando la ganancia de color opuesta.iOS Devices compensate for color casts by boosting the opposite color gain. Por ejemplo, si una escena tiene demasiado azul, el aumento rojo se incrementará para compensar.For instance, if a scene has too much blue, then the red gain will be boosted to compensate. Estos valores de ganancia se calibran para dispositivos específicos para que sean dependientes del dispositivo.These gain values are calibrated for specific devices so they are device dependent.

Controles de balance de blanco existentesExisting White Balance Controls

iOS 7 y versiones posteriores proporcionaron los siguientes controles de balance de blanco existentes a través de WhiteBalanceMode propiedad:iOS 7 and above provided the following existing White Balance controls via WhiteBalanceMode property:

  • AVCapture WhiteBalance ModeLocked: muestrea la escena una vez y usa esos valores a lo largo de la escena.AVCapture WhiteBalance ModeLocked – Samples the scene once and using those values throughout the scene.
  • AVCapture WhiteBalance ModeContinuousAutoExposure: muestrea la escena continuamente para asegurarse de que está bien equilibrada.AVCapture WhiteBalance ModeContinuousAutoExposure – Samples the scene continuously to ensure that it is well balanced.

Y la aplicación puede supervisar la propiedad AdjustingWhiteBalance para ver cuándo se está ajustando la exposición.And the application can monitor the AdjustingWhiteBalance property to see when exposure is being adjusted.

Nuevos controles de equilibrio de blancos en iOS 8New White Balance Controls in iOS 8

Además de las características ya proporcionadas por iOS 7 y versiones posteriores, las siguientes características están ahora disponibles para controlar el equilibrio de blancos en iOS 8:In addition to the features already provided by iOS 7 and above, the following features are now available to control White Balance in iOS 8:

  • Control totalmente manual del aumento de RGB del dispositivo.Fully manual control of the device RGB gains.
  • Get, Set y key-value observan el aumento de RGB del dispositivo.Get, Set and Key-Value Observe the device RGB gains.
  • Compatibilidad con el balance de blanco mediante una tarjeta gris.Support for White Balance using a Gray Card.
  • Rutinas de conversión a y desde espacios de colores independientes del dispositivo.Conversion routines to and from device independent color spaces.

Para implementar las características anteriores, se ha agregado la estructura de AVCaptureWhiteBalanceGain con los siguientes miembros:To implement the above features, the AVCaptureWhiteBalanceGain structure has been added with the following members:

  • RedGain
  • GreenGain
  • BlueGain

La ganancia máxima de balance de blanco es actualmente cuatro (4) y puede estar preparada desde la propiedad MaxWhiteBalanceGain.The maximum white balance gain is currently four (4) and can be ready from the MaxWhiteBalanceGain property. Por lo tanto, el intervalo válido es de uno (1) a MaxWhiteBalanceGain (4) actualmente.So the legal range is from one (1) to MaxWhiteBalanceGain (4) currently.

La propiedad DeviceWhiteBalanceGains se puede utilizar para observar los valores actuales.The DeviceWhiteBalanceGains property can be used to observe the current values. Use SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains para ajustar el saldo de ganancia cuando la cámara está en el modo de equilibrio de blanco bloqueado.Use SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains to adjust the balance gains when the camera is in the locked white balance mode.

Rutinas de conversiónConversion Routines

Se han agregado rutinas de conversión a iOS 8 para ayudar en la conversión de espacios de colores independientes del dispositivo a y desde ellos.Conversion routines have been added to iOS 8 to help with converting to, and from, device independent color spaces. Para implementar las rutinas de conversión, se ha agregado la estructura de AVCaptureWhiteBalanceChromaticityValues con los siguientes miembros:To implement the conversion routines, the AVCaptureWhiteBalanceChromaticityValues structure has been added with the following members:

  • X: es un valor comprendido entre 0 y 1.X - is a value from 0 to 1.
  • Y: es un valor comprendido entre 0 y 1.Y - is a value from 0 to 1.

También se ha agregado una estructura de AVCaptureWhiteBalanceTemperatureAndTintValues con los siguientes miembros:An AVCaptureWhiteBalanceTemperatureAndTintValues structure has also been added with the following members:

  • Temperature: es un valor de punto flotante en grados Kelvin.Temperature - is a floating point value in degrees Kelvin.
  • Tint: es un desplazamiento de verde o magenta desde 0 a 150 con valores positivos hacia la dirección verde y negativos hacia el magenta.Tint - is an offset from green or magenta from 0 to 150 with positive values towards the green direction and negative toward in the magenta.

Utilice los métodos CaptureDevice.GetTemperatureAndTintValuesy CaptureDevice.GetDeviceWhiteBalanceGainspara convertir entre los espacios de colores de la temperatura y del matiz, la cromaticidad y la ganancia de RGB.Use the CaptureDevice.GetTemperatureAndTintValuesand the CaptureDevice.GetDeviceWhiteBalanceGainsmethods to convert between temperature and tint, chromaticity and RGB gain color spaces.

Nota

Las rutinas de conversión son más precisas cuanto más se acerque el valor que se va a convertir a Planckian raíz.The conversion routines are more accurate the closer the value to be converted is to the Planckian Locus.

Compatibilidad con tarjetas grisesGray Card Support

Apple usa el término "mundo gris" para hacer referencia a la compatibilidad con tarjetas atenuadas integradas en iOS 8.Apple uses the term Gray World to refer to the Gray Card support built into iOS 8. Permite al usuario centrarse en una tarjeta gris física que cubre al menos el 50% del centro del fotograma y lo usa para ajustar el balance de blanco.It allows the user to focus on a physical Gray Card that covers at least 50% of the center of the frame and uses that to adjust the White Balance. El propósito de la tarjeta gris es conseguir un blanco que parezca neutro.The purpose of the Gray Card is to achieve white that appears neutral.

Esto se puede implementar en una aplicación solicitando al usuario que coloque una tarjeta gris física delante de la cámara, supervisando la propiedad GrayWorldDeviceWhiteBalanceGains y esperando hasta que los valores se liquiden.This can be implemented in an application by prompting the user to place a physical gray card in front of the camera, monitoring the GrayWorldDeviceWhiteBalanceGains property and waiting until the values settle down.

A continuación, la aplicación bloqueará las ganancias de equilibrio de blanco para el método SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains usando los valores de la propiedad GrayWorldDeviceWhiteBalanceGains para aplicar los cambios.The application would then lock the White Balance gains for the SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains method using the values from the GrayWorldDeviceWhiteBalanceGains property to apply the changes.

El dispositivo de captura debe estar bloqueado para la configuración antes de que se pueda realizar un cambio en el equilibrio de blanco.The Capture Device must be locked for configuration before a change in White Balance can be made.

Ejemplo manual de balance de blancoManual White Balance Example

Con el código de configuración de la captura de AV general en su lugar, se puede Agregar un UIViewController al guión gráfico de la aplicación y configurarlo de la manera siguiente:With the General AV Capture Setup code in place, a UIViewController can be added to the application's Storyboard and configured as follows:

La vista contiene los siguientes elementos principales:The view contains the following main elements:

  • UIImageView que mostrará la fuente de vídeo.A UIImageView that will display the video feed.
  • UISegmentedControl que cambiará el modo de enfoque de automático a bloqueado.A UISegmentedControl that will change the Focus Mode from Automatic to Locked.
  • Dos UISlider controles que mostrarán y actualizarán la temperatura y el matiz.Two UISlider controls that will show and update the Temperature and Tint.
  • UIButton que se usa para muestrear un espacio de tarjeta gris (mundo gris) y establecer el balance de blanco con esos valores.A UIButton used to sample a Gray Card (Gray World) space and set the White Balance using those values.

Realice lo siguiente para conectar el controlador de vista para el control manual de balance de blanco:Do the following to wire-up the view controller for Manual White Balance Control:

  1. Agregue las siguientes instrucciones Using:Add the following using statements:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Agregue las siguientes variables privadas:Add the following private variables:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Agregue las siguientes propiedades calculadas:Add the following computed properties:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Agregue el siguiente método privado para establecer el nuevo equilibrio de blanco temperatura y matiz:Add the following private method to set the new white balance Temperature and Tint:

    #region Private Methods
    void SetTemperatureAndTint() {
        // Grab current temp and tint
        var TempAndTint = new AVCaptureWhiteBalanceTemperatureAndTintValues (Temperature.Value, Tint.Value);
    
        // Convert Color space
        var gains = ThisApp.CaptureDevice.GetDeviceWhiteBalanceGains (TempAndTint);
    
        // Set the new values
        if (ThisApp.CaptureDevice.LockForConfiguration (out Error)) {
            gains = NomralizeGains (gains);
            ThisApp.CaptureDevice.SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains (gains, null);
            ThisApp.CaptureDevice.UnlockForConfiguration ();
        }
    }
    
    AVCaptureWhiteBalanceGains NomralizeGains (AVCaptureWhiteBalanceGains gains)
    {
        gains.RedGain = Math.Max (1, gains.RedGain);
        gains.BlueGain = Math.Max (1, gains.BlueGain);
        gains.GreenGain = Math.Max (1, gains.GreenGain);
    
        float maxGain = ThisApp.CaptureDevice.MaxWhiteBalanceGain;
        gains.RedGain = Math.Min (maxGain, gains.RedGain);
        gains.BlueGain = Math.Min (maxGain, gains.BlueGain);
        gains.GreenGain = Math.Min (maxGain, gains.GreenGain);
    
        return gains;
    }
    #endregion
    
  5. Invalide el método ViewDidLoad y agregue el código siguiente:Override the ViewDidLoad method and add the following code:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Set min and max values
        Temperature.MinValue = 1000f;
        Temperature.MaxValue = 10000f;
    
        Tint.MinValue = -150f;
        Tint.MaxValue = 150f;
    
        // Create a timer to monitor and update the UI
        SampleTimer = new Timer (5000);
        SampleTimer.Elapsed += (sender, e) => {
            // Convert color space
            var TempAndTint = ThisApp.CaptureDevice.GetTemperatureAndTintValues (ThisApp.CaptureDevice.DeviceWhiteBalanceGains);
    
            // Update slider positions
            Temperature.BeginInvokeOnMainThread (() => {
                Temperature.Value = TempAndTint.Temperature;
            });
    
            Tint.BeginInvokeOnMainThread (() => {
                Tint.Value = TempAndTint.Tint;
            });
        };
    
        // Watch for value changes
        Segments.ValueChanged += (sender, e) => {
            // Lock device for change
            if (ThisApp.CaptureDevice.LockForConfiguration (out Error)) {
    
                // Take action based on the segment selected
                switch (Segments.SelectedSegment) {
                case 0:
                // Activate auto focus and start monitoring position
                    Temperature.Enabled = false;
                    Tint.Enabled = false;
                    ThisApp.CaptureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance;
                    SampleTimer.Start ();
                    Automatic = true;
                    break;
                case 1:
                // Stop auto focus and allow the user to control the camera
                    SampleTimer.Stop ();
                    ThisApp.CaptureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.Locked;
                    Automatic = false;
                    Temperature.Enabled = true;
                    Tint.Enabled = true;
                    break;
                }
    
                // Unlock device
                ThisApp.CaptureDevice.UnlockForConfiguration ();
            }
        };
    
        // Monitor position changes
        Temperature.TouchUpInside += (sender, e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic)
                return;
    
            // Update white balance
            SetTemperatureAndTint ();
        };
    
        Tint.TouchUpInside += (sender, e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic)
                return;
    
            // Update white balance
            SetTemperatureAndTint ();
        };
    
        GrayCardButton.TouchUpInside += (sender, e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic)
                return;
    
            // Get gray card values
            var gains = ThisApp.CaptureDevice.GrayWorldDeviceWhiteBalanceGains;
    
            // Set the new values
            if (ThisApp.CaptureDevice.LockForConfiguration (out Error)) {
                ThisApp.CaptureDevice.SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains (gains, null);
                ThisApp.CaptureDevice.UnlockForConfiguration ();
            }
        };
    }
    
  6. Invalide el método ViewDidAppear y agregue lo siguiente para iniciar la grabación cuando se cargue la vista:Override the ViewDidAppear method and add the following to start recording when the view loads:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
            SampleTimer.Start ();
        }
    }
    
  7. Guarde los cambios en el código y ejecute la aplicación.Save the changes the to code and run the application.

  8. Con la cámara en el modo auto, los controles deslizantes se mueven automáticamente a medida que la cámara ajusta el balance de blanco:With the camera in the Auto mode, the sliders will move automatically as the camera adjusts white balance:

  9. Puntee en el segmento bloqueado y arrastre los controles deslizantes Temp y matiz para ajustar el balance de blanco manualmente:Tap the Locked segment and drag the Temp and Tint sliders to adjust the white balance manually:

  10. Con el segmento bloqueado todavía seleccionado, coloque una tarjeta gris física delante de la cámara y pulse el botón de la tarjeta gris para ajustar el balance blanco al mundo gris:With the Locked segment still selected, place a physical gray card in front of the camera and tap the Gray Card button to adjust white balance to the Gray World:

  11. Detenga la aplicación.Stop the application.

En el código anterior se ha mostrado cómo supervisar la configuración de equilibrio de blanco cuando la cámara está en modo automático o usar controles deslizantes para controlar el equilibrio de blanco cuando está en modo bloqueado.The above code has shown how to monitor the white balance settings when the camera is in the Automatic mode or use sliders to control the white balance when it is in the Locked mode.

Captura entre corchetesBracketed Capture

La captura entre corchetes se basa en la configuración de los controles de la cámara manual presentada anteriormente y permite a la aplicación capturar un momento dado, de varias maneras diferentes.The Bracketed Capture is based on the settings from the Manual Camera Controls presented above and allows the application to capture a moment in time, in a variety of different ways.

Simplemente se ha indicado que la captura entre corchetes es una ráfaga de imágenes fijas tomadas con una variedad de opciones de imagen a imagen.Simply stated, Bracketed Capture is a burst of still images taken with a variety of settings from picture to picture.

Con la captura entre corchetes de iOS 8, una aplicación puede establecer valores predeterminados de una serie de controles de cámara manuales, emitir un solo comando y hacer que la escena actual devuelva una serie de imágenes para cada uno de los valores preestablecidos manuales.Using the Bracketed Capture in iOS 8, an application can preset a series of Manual Camera Controls, issue a single command and have the current scene return a series of images for each of the manual presets.

Aspectos básicos de la captura entre corchetesBracketed Capture Basics

De nuevo, la captura entre corchetes es una ráfaga de imágenes fijas tomadas con distintos valores de la imagen a la imagen.Again, Bracketed Capture is a burst of still images taken with varied settings from picture to picture. Los tipos de captura entre corchetes disponibles son:The types of Bracketed Capture available are:

  • Corchete de exposición automática , donde todas las imágenes tienen una cantidad de sesgo variable.Auto Exposure Bracket – where all images have a varied Bias amount.
  • Corchete de exposición manual , donde todas las imágenes tienen una velocidad de obturador variable (duración) y una cantidad ISO.Manual Exposure Bracket – where all images have a varied Shutter Speed (Duration) and ISO amount.
  • Corchete de ráfaga simple : una serie de imágenes fijas tomadas en una sucesión rápida.Simple Burst Bracket – A series of still images taken in rapid succession.

Nuevos controles de captura entre corchetes en iOS 8New Bracketed Capture Controls in iOS 8

Todos los comandos de captura entre corchetes se implementan en la clase AVCaptureStillImageOutput.All Bracketed Capture commands are implemented in the AVCaptureStillImageOutput class. Utilice el método CaptureStillImageBracketpara obtener una serie de imágenes con la matriz de valores especificada.Use the CaptureStillImageBracketmethod to get a series of images with the given array of settings.

Se han implementado dos nuevas clases para controlar la configuración:Two new classes have been implemented to handle settings:

  • AVCaptureAutoExposureBracketedStillImageSettings: tiene una propiedad, ExposureTargetBias, que se usa para establecer la diferencia para un corchete de exposición automática.AVCaptureAutoExposureBracketedStillImageSettings – It has one property, ExposureTargetBias, used to set the bias for an auto exposure bracket.
  • AVCaptureManual``ExposureBracketedStillImageSettings: tiene dos propiedades, ExposureDuration y ISO, que se usan para establecer la velocidad del obturador y el ISO para un corchete de exposición manual.AVCaptureManual ExposureBracketedStillImageSettings – It has two properties, ExposureDuration and ISO, used to set the shutter speed and ISO for a manual exposure bracket.

Los controles de captura entre corchetes hacen y noBracketed Capture Controls Do's and Don'ts

HacerDo's

A continuación se muestra una lista de las cosas que deben realizarse cuando se usan los controles de captura entre corchetes en iOS 8:The following is a list of things that should be done when using the Bracketed Capture controls in iOS 8:

  • Prepare la aplicación para la situación de captura en el peor de los casos llamando al método PrepareToCaptureStillImageBracket.Prepare the app for the worst-case capture situation by calling the PrepareToCaptureStillImageBracket method.
  • Suponga que los búferes de ejemplo van a provienen del mismo grupo compartido.Assume that the sample buffers are going to come from the same shared pool.
  • Para liberar la memoria asignada por una llamada a Prepare anterior, llame de nuevo a PrepareToCaptureStillImageBracket y envíelo a una matriz de un objeto.To release the memory that was allocated by a previous prepare call, call PrepareToCaptureStillImageBracket again and send it an array of one object.

Qué no hacerDon'ts

A continuación se muestra una lista de las cosas que no se deben realizar cuando se usan los controles de captura entre corchetes en iOS 8:The following is a list of things that should not be done when using the Bracketed Capture controls in iOS 8:

  • No mezcle tipos de configuración de captura entre corchetes en una sola captura.Don't mix Bracketed Capture settings types in a single capture.
  • No solicite más de MaxBracketedCaptureStillImageCount imágenes en una sola captura.Don't request more than MaxBracketedCaptureStillImageCount images in a single capture.

Detalles de la captura entre corchetesBracketed Capture Details

Se deben tener en cuenta los siguientes detalles al trabajar con la captura entre corchetes en iOS 8:The following details should be taken into consideration when working with Bracketed Capture in iOS 8:

  • La configuración entre corchetes invalida temporalmente la configuración de AVCaptureDevice.Bracketed settings temporarily override the AVCaptureDevice settings.
  • Se omite la configuración de la estabilización de imágenes y de Flash.Flash and still image stabilization settings are ignored.
  • Todas las imágenes deben usar el mismo formato de salida (JPEG, PNG, etc.).All images must use the same output format (jpeg, png, etc.)
  • La vista previa de vídeo puede quitar fotogramas.Video preview may drop frames.
  • La captura entre corchetes se admite en todos los dispositivos compatibles con iOS 8.Bracketed Capture is supported on all devices compatible with iOS 8.

Teniendo en cuenta esta información, echemos un vistazo a un ejemplo del uso de la captura entre corchetes en iOS 8.With this information in mind, let's take a look at an example of using Bracketed Capture in iOS 8.

Ejemplo de captura de corchetesBracket Capture Example

Con el código de configuración de la captura de AV general en su lugar, se puede Agregar un UIViewController al guión gráfico de la aplicación y configurarlo de la manera siguiente:With the General AV Capture Setup code in place, a UIViewController can be added to the application's Storyboard and configured as follows:

La vista contiene los siguientes elementos principales:The view contains the following main elements:

  • UIImageView que mostrará la fuente de vídeo.A UIImageView that will display the video feed.
  • Tres UIImageViews que mostrarán los resultados de la captura.Three UIImageViews that will display the results of the capture.
  • UIScrollView para alojar las vistas de fuente de vídeo y resultado.A UIScrollView to house the video feed and result views.
  • UIButton que se usa para realizar una captura entre corchetes con algunas configuraciones preestablecidas.A UIButton used to take a Bracketed Capture with some preset settings.

Realice lo siguiente para conectar el controlador de vista para la captura entre corchetes:Do the following to wire-up the view controller for Bracketed Capture:

  1. Agregue las siguientes instrucciones Using:Add the following using statements:

    using System;
    using System.Drawing;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using CoreImage;
    
  2. Agregue las siguientes variables privadas:Add the following private variables:

    #region Private Variables
    private NSError Error;
    private List<UIImageView> Output = new List<UIImageView>();
    private nint OutputIndex = 0;
    #endregion
    
  3. Agregue las siguientes propiedades calculadas:Add the following computed properties:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    #endregion
    
  4. Agregue el siguiente método privado para compilar las vistas de imagen de salida requeridas:Add the following private method to build the required output image views:

    #region Private Methods
    private UIImageView BuildOutputView(nint n) {
    
        // Create a new image view controller
        var imageView = new UIImageView (new CGRect (CameraView.Frame.Width * n, 0, CameraView.Frame.Width, CameraView.Frame.Height));
    
        // Load a temp image
        imageView.Image = UIImage.FromFile ("Default-568h@2x.png");
    
        // Add a label
        UILabel label = new UILabel (new CGRect (0, 20, CameraView.Frame.Width, 24));
        label.TextColor = UIColor.White;
        label.Text = string.Format ("Bracketed Image {0}", n);
        imageView.AddSubview (label);
    
        // Add to scrolling view
        ScrollView.AddSubview (imageView);
    
        // Return new image view
        return imageView;
    }
    #endregion
    
  5. Invalide el método ViewDidLoad y agregue el código siguiente:Override the ViewDidLoad method and add the following code:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Setup scrolling area
        ScrollView.ContentSize = new SizeF (CameraView.Frame.Width * 4, CameraView.Frame.Height);
    
        // Add output views
        Output.Add (BuildOutputView (1));
        Output.Add (BuildOutputView (2));
        Output.Add (BuildOutputView (3));
    
        // Create preset settings
        var Settings = new AVCaptureBracketedStillImageSettings[] {
            AVCaptureAutoExposureBracketedStillImageSettings.Create(-2.0f),
            AVCaptureAutoExposureBracketedStillImageSettings.Create(0.0f),
            AVCaptureAutoExposureBracketedStillImageSettings.Create(2.0f)
        };
    
        // Wireup capture button
        CaptureButton.TouchUpInside += (sender, e) => {
            // Reset output index
            OutputIndex = 0;
    
            // Tell the camera that we are getting ready to do a bracketed capture
            ThisApp.StillImageOutput.PrepareToCaptureStillImageBracket(ThisApp.StillImageOutput.Connections[0],Settings,async (bool ready, NSError err) => {
                // Was there an error, if so report it
                if (err!=null) {
                    Console.WriteLine("Error: {0}",err.LocalizedDescription);
                }
            });
    
            // Ask the camera to snap a bracketed capture
            ThisApp.StillImageOutput.CaptureStillImageBracket(ThisApp.StillImageOutput.Connections[0],Settings, (sampleBuffer, settings, err) =>{
                // Convert raw image stream into a Core Image Image
                var imageData = AVCaptureStillImageOutput.JpegStillToNSData(sampleBuffer);
                var image = CIImage.FromData(imageData);
    
                // Display the resulting image
                Output[OutputIndex++].Image = UIImage.FromImage(image);
    
                // IMPORTANT: You must release the buffer because AVFoundation has a fixed number
                // of buffers and will stop delivering frames if it runs out.
                sampleBuffer.Dispose();
            });
        };
    }
    
  6. Invalide el método ViewDidAppear y agregue el código siguiente:Override the ViewDidAppear method and add the following code:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
        }
    }
    
    
  7. Guarde los cambios en el código y ejecute la aplicación.Save the changes the to code and run the application.

  8. Enmarcar una escena y pulsar el botón de corchete de captura:Frame a scene and tap the Capture Bracket button:

  9. Deslice el dedo de derecha a izquierda para ver las tres imágenes tomadas por la captura entre corchetes:Swipe right to left to see the three images taken by the Bracketed Capture:

  10. Detenga la aplicación.Stop the application.

En el código anterior se ha mostrado cómo configurar y realizar una captura entre corchetes de exposición automática en iOS 8.The above code has shown how to configure and take an Auto Exposure Bracketed Capture in iOS 8.

ResumenSummary

En este artículo se ha tratado una introducción a los nuevos controles de cámara manuales que proporciona iOS 8 y se han tratado los aspectos básicos de lo que hacen y cómo funcionan.In this article we have covered an introduction to the new Manual Camera Controls provided by iOS 8 and covered the basics of what they do and how they work. Hemos proporcionado ejemplos de enfoque manual, exposición manual y balance manual de blancos.We have given examples of Manual Focus, Manual Exposure and Manual White Balance. Por último, hemos dado un ejemplo en el que se realiza una captura entre corchetes mediante los controles de cámara manuales descritos anteriormente.Finally, we gave an example taking a Bracketed Capture using the previously discussed Manual Camera Controls