Controles de cámara manuales en Xamarin.iOS
Los controles manuales de Cámara, proporcionados por AVFoundation Framework
en iOS 8, permiten que una aplicación móvil tome el control total sobre la cámara de un dispositivo con iOS. Este nivel de control específico se puede usar para crear aplicaciones de cámara de nivel profesional y proporcionar composiciones artísticas mediante el ajuste de los parámetros de la cámara mientras se toma una imagen fija o un vídeo.
Estos controles también pueden ser útiles al desarrollar aplicaciones científicas o industriales, donde los resultados están menos orientados a la corrección o belleza de la imagen, y están orientados más hacia resaltar alguna característica o elemento de la imagen que se está tomando.
Objetos de captura de AVFoundation
Tanto si se toman vídeos o imágenes fijas con la cámara en un dispositivo con iOS, el proceso que se usa para capturar esas imágenes es en gran medida el mismo. Esto es cierto en las aplicaciones que usan los controles de cámara automatizados predeterminados o los que aprovechan los nuevos controles de cámara manuales:
La entrada se toma de un AVCaptureDeviceInput
en un AVCaptureSession
mediante un AVCaptureConnection
. El resultado es la salida como una imagen fija o como una secuencia de vídeo. Un AVCaptureDevice
controla todo el proceso.
Controles manuales proporcionados
Con las nuevas API proporcionadas por iOS 8, la aplicación puede tomar el control de las siguientes características de cámara:
- Enfoque manual: al permitir que el usuario final tome el control del enfoque directamente, una aplicación puede proporcionar más control sobre la imagen tomada.
- Exposición manual: al proporcionar control manual sobre la exposición, una aplicación puede proporcionar más libertad a los usuarios y permitirles lograr un aspecto estilizado.
- Balance de blancos manual: el balance de blancos se usa para ajustar el color de una imagen, a menudo para que parezca realista. Según la fuente de luz hay una temperatura de color diferente y la configuración de la cámara utilizada para capturar una imagen se ajusta para compensar estas diferencias. De nuevo, al permitir el control del usuario sobre el balance de blancos, los usuarios pueden realizar ajustes que no se pueden realizar automáticamente.
iOS 8 proporciona extensiones y mejoras a las API de iOS existentes para proporcionar este control específico sobre el proceso de captura de la imagen.
Requisitos
Se requiere lo siguiente para completar los pasos presentados en este artículo:
- Xcode 7+ e iOS 8 o posterior: las API de Xcode 7 e iOS 8 o más recientes de Apple deben instalarse y configurarse en el equipo del desarrollador.
- Visual Studio para Mac: la versión más reciente de Visual Studio para Mac debe instalarse y configurarse en el dispositivo de usuario.
- Dispositivo con iOS 8: un dispositivo con iOS que ejecute la versión más reciente de iOS 8. Las características de la cámara no se pueden probar en el simulador de iOS.
Configuración general de captura de AV
Al grabar vídeo en un dispositivo con iOS, hay algún código de configuración general que siempre es necesario. En esta sección se trata la configuración mínima necesaria para grabar vídeo desde la cámara del dispositivo con iOS y mostrar ese vídeo en tiempo real en un UIImageView
.
Delegado de búfer de ejemplo de salida
Una de las primeras cosas necesarias será un delegado para supervisar el búfer de salida de ejemplo y mostrar una imagen capturada del búfer a un UIImageView
en la interfaz de usuario de la aplicación.
La siguiente rutina supervisará el búfer de ejemplo y actualizará la interfaz de usuario:
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
}
}
Con esta rutina en su lugar, AppDelegate
se puede modificar para abrir una sesión de captura de AV para grabar una fuente de vídeo en directo.
Crear una sesión de captura de AV
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 con iOS y es necesaria para obtener un vídeo en una aplicación de iOS. Dado que la aplicación de ejemplo ManualCameraControl
usa la sesión de captura en varios lugares diferentes, se configurará en AppDelegate
y estará disponible para toda la aplicación.
Haga lo siguiente para modificar el AppDelegate
de la aplicación y agregue el código necesario:
Haga doble clic en el archivo
AppDelegate.cs
en el Explorador de soluciones para abrirlo para su edición.Agregue las siguientes instrucciones using en la parte superior del archivo :
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;
Agregue las siguientes variables privadas y propiedades calculadas a la clase
AppDelegate
:#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
Invalide el método terminado y cámbielo a:
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; }
Guarde los cambios en el archivo.
Con este código implementado, los controles de Cámara manuales se pueden implementar fácilmente para la experimentación y las pruebas.
Enfoque manual
Al permitir que el usuario final tome los controles del enfoque directamente, una aplicación puede proporcionar más control artístico sobre la imagen tomada.
Por ejemplo, un fotógrafo profesional puede suavizar el enfoque de una imagen para lograr un efecto bokeh. O bien, cree un efecto de extracción de enfoque.
Para los científicos o un escritor de aplicaciones médicas, es posible que la aplicación quiera mover mediante programación la lente para experimentos. La nueva API permite al usuario final o a la aplicación tomar el control sobre el enfoque en el momento en que se toma la imagen.
Funcionamiento del enfoque
Antes de analizar los detalles del control del foco en una aplicación de iOS 8. Echemos un vistazo rápido a cómo funciona el enfoque en un dispositivo con iOS:
La luz entra en la lente de la cámara del dispositivo con iOS y se centra en un sensor de imagen. La distancia de la lente desde los controles del sensor donde el punto focal (el área donde la imagen aparecerá más nítida) está en relación con el sensor. Cuanto más lejos esté la lente del sensor, los objetos distantes parecen más nítidos y los objetos cercanos parecen más nítidos.
En un dispositivo con iOS, la lente se mueve más cerca o más lejos del sensor por imanes y muelles. Como resultado, el posicionamiento exacto de la lente es imposible, ya que variará de un dispositivo a otro, y puede verse afectado por parámetros como la orientación del dispositivo o la antigüedad del dispositivo y los muelles.
Términos de enfoque importantes
Cuando se trabaja con el enfoque, hay algunos términos con los que el desarrollador debe estar familiarizado:
- Profundidad del campo: la distancia entre los objetos más cercanos y más lejanos enfocados.
- Macro: este es el extremo cercano del espectro de enfoque y es la distancia más cercana a la que la lente puede enfocarse.
- Infinito: este es el extremo lejano del espectro de enfoque y es la distancia más lejana a la que la lente puede enfocarse.
- Distancia hiperfocal: este es el punto del espectro del enfoque donde el objeto más lejano del marco está justo en la parte más lejana del enfoque. En otras palabras, esta es la posición del enfoque que maximiza la profundidad del campo.
- Posición de la lente: eso es lo que controla todos los términos anteriores. Esta es la distancia de la lente desde el sensor y, por tanto, el controlador del foco.
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.
Controles de enfoque existentes
iOS 7 y versiones anteriores, proporcionaron controles de enfoque existentes a través de la propiedad FocusMode
como:
AVCaptureFocusModeLocked
: el enfoque está bloqueado en un único punto focal.AVCaptureFocusModeAutoFocus
: la cámara barre la lente a través de todos los puntos focales hasta que encuentra el enfoque nítido y luego permanece allí.AVCaptureFocusModeContinuousAutoFocus
: la cámara se vuelve a enfocar cada vez que detecta una condición fuera del enfoque.
Los controles existentes también proporcionaron un punto de interés establecido a través de la propiedad FocusPointOfInterest
para que el usuario pueda pulsar para enfocar en un área determinada. La aplicación también puede realizar un seguimiento del movimiento de la lente supervisando la propiedad IsAdjustingFocus
.
Además, la propiedad AutoFocusRangeRestriction
proporcionó una restricción de intervalo como:
AVCaptureAutoFocusRangeRestrictionNear
: restringe el enfoque automático a profundidades cercanas. Resulta útil en situaciones como escanear un código QR o un código de barras.AVCaptureAutoFocusRangeRestrictionFar
: restringe el enfoque automático a profundidades lejanas. Resulta útil en situaciones en las que los objetos que se sabe que son irrelevantes están en el campo de visión (por ejemplo, un marco de ventana).
Por último, la propiedad SmoothAutoFocus
ralentiza el algoritmo de enfoque automático y lo pasa en incrementos más pequeños para evitar mover artefactos al grabar vídeo.
Nuevos controles de enfoque en iOS 8
Además de las características ya proporcionadas por iOS 7 y las versiones posteriores, las siguientes características ahora están disponibles para controlar el enfoque en iOS 8:
- Control manual total de la posición de la lente al bloquear el enfoque.
- Observación clave-valor de la posición de la lente en cualquier modo de enfoque.
Para implementar las características anteriores, la clase AVCaptureDevice
se ha modificado para incluir una propiedad LensPosition
de solo lectura utilizada para obtener la posición actual de la lente de la cámara.
Para controlar manualmente la posición de la lente, el dispositivo de captura debe estar en el modo de enfoque bloqueado. Ejemplo:
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. Se puede proporcionar una rutina de devolución de llamada opcional para obtener notificaciones cuando el cambio surte efecto. Ejemplo:
ThisApp.CaptureDevice.LockForConfiguration(out Error);
ThisApp.CaptureDevice.SetFocusModeLocked(Position.Value,null);
ThisApp.CaptureDevice.UnlockForConfiguration();
Como se muestra 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 lente. Los valores válidos de posición de lente están comprendidos entre 0,0 y 1,0.
Ejemplo de enfoque manual
Con el código general de instalación de captura de AV en su lugar, se puede agregar un UIViewController
al Storyboard de la aplicación y configurarlo como se indica a continuación:
La vista contiene los siguientes elementos principales:
- Un
UIImageView
que mostrará la fuente de vídeo. - Un
UISegmentedControl
que cambiará el modo de enfoque de Automático a Bloqueado. - Un
UISlider
que mostrará y actualizará la posición actual de lente.
Haga lo siguiente para conectar el controlador de vista para el control de enfoque manual:
Agregue las siguientes instrucciones using:
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;
Agregue las variables privadas siguientes:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
Agregue las siguientes propiedades calculadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Invalide el método
ViewDidLoad
y agregue el código siguiente: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(); }; }
Invalide el método
ViewDidAppear
y agregue lo siguiente para empezar la grabación cuando se cargue la vista: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 (); } }
Con la cámara en el modo Automático, el control deslizante se moverá automáticamente a medida que la cámara ajusta el enfoque:
Pulse el segmento Bloqueado y arrastre el control deslizante de posición para ajustar la posición de la lente manualmente:
Detenga la aplicación.
El código anterior 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 el modo Bloqueado.
Exposición manual
La exposición hace referencia al brillo de una imagen en relación con el brillo de origen y se determina mediante la cantidad de luz que alcanza el sensor, durante cuánto tiempo y por el nivel de ganancia del sensor (asignación ISO). Al proporcionar control manual sobre la exposición, una aplicación puede proporcionar más libertad al usuario final y permitirle lograr un aspecto estilizado.
Con los controles de exposición manual, el usuario puede pasar una imagen de tener un brillo poco realista a ser oscura y taciturna:
De nuevo, esto se puede hacer automáticamente mediante el control mediante programación para aplicaciones científicas o a través de controles manuales proporcionados por la interfaz de usuario de las aplicaciones. En cualquier caso, las nuevas API de exposición de iOS 8 proporcionan un control específico sobre la configuración de exposición de la cámara.
Cómo funciona la exposición
Antes de analizar los detalles del control de la exposición en una aplicación de iOS 8. Echemos un vistazo rápido a cómo funciona la exposición:
Los tres elementos básicos que se unen para controlar la exposición son:
- Velocidad del obturador: es el tiempo que el obturador está abierto para permitir la luz en el sensor de la cámara. Cuanto menor sea el tiempo que el obturador está abierto, menos luz se deja entrar y más nítida será la imagen (menos desenfoque de movimiento). Cuanto más tiempo esté abierto el obturador, más luz se deja entrar y más desenfoque de movimiento se produce.
- Sensibilidad ISO: se trata de un término prestado de la fotografía cinematográfica y hace referencia a la sensibilidad de los productos químicos de la película a la luz. Los valores ISO bajos en película tienen menos grano y reproducción de color más fino; Los valores ISO bajos en los sensores digitales tienen menos ruido del sensor, pero menos brillo. Cuanto mayor sea el valor ISO, más brillante será la imagen, pero con más ruido del sensor. "ISO" en un sensor digital es una medida de ganancia electrónica, no una característica física.
- Apertura de lente: este es el tamaño de la apertura de la lente. En todos los dispositivos iOS, la apertura de la lente es fija, por lo que los dos únicos valores que se pueden usar para ajustar la exposición son la velocidad de obturación e ISO.
Cómo funciona la exposición automática continua
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 con iOS.
En primer lugar está el bloqueo de exposición automática, que tiene el trabajo de calcular la exposición ideal y se alimenta continuamente de las estadísticas de medición. Utiliza esta información para calcular la combinación óptima de ISO y velocidad de obturación para que la escena esté bien iluminada. Este ciclo se conoce como bucle AE.
Cómo funciona la exposición bloqueada
A continuación, vamos a examinar cómo funciona la exposición bloqueada en dispositivos con iOS.
De nuevo, tiene el bloqueo de exposición automática que intenta calcular los valores óptimos de iOS y Duración. Sin embargo, en este modo, el bloqueo AE está desconectado del motor de estadísticas de medición.
Controles de exposición existentes
En iOS 7 y las versiones posteriores, proporcione los siguientes controles de exposición existentes a través de la propiedad ExposureMode
:
AVCaptureExposureModeLocked
: muestra la escena una vez y usa esos valores en toda la escena.AVCaptureExposureModeContinuousAutoExposure
: muestrea la escena continuamente para asegurarse de que está bien iluminada.
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 ajusta la exposición.
Nuevos controles de exposición en iOS 8
Además de las características ya proporcionadas por iOS 7 y las versiones posteriores, las siguientes características ahora están disponibles para controlar la exposición en iOS 8:
- Exposición personalizada totalmente manual.
- Obtener, establecer y observar valores clave de IOS y la velocidad de obturación (duración).
Para implementar las características anteriores, se ha agregado un nuevo modo AVCaptureExposureModeCustom
. Cuando la cámara en es el modo personalizado, se puede usar el código siguiente para ajustar la duración de exposición e ISO:
CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.LockExposure(DurationValue,ISOValue,null);
CaptureDevice.UnlockForConfiguration();
En los modos Automático y Bloqueado, la aplicación puede ajustar el bias de la rutina de exposición automática mediante el código siguiente:
CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.SetExposureTargetBias(Value,null);
CaptureDevice.UnlockForConfiguration();
Los intervalos de configuración mínimo y máximo dependen del dispositivo en el que se ejecuta la aplicación, por lo que nunca deben codificarse de forma rígida. En su lugar, use las siguientes propiedades para obtener los intervalos de valor mínimo y máximo:
CaptureDevice.MinExposureTargetBias
CaptureDevice.MaxExposureTargetBias
CaptureDevice.ActiveFormat.MinISO
CaptureDevice.ActiveFormat.MaxISO
CaptureDevice.ActiveFormat.MinExposureDuration
CaptureDevice.ActiveFormat.MaxExposureDuration
Como se muestra 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 exposición.
Ejemplo de exposición manual
Con el código general de instalación de captura de AV en su lugar, se puede agregar un UIViewController
al Storyboard de la aplicación y configurarlo como se indica a continuación:
La vista contiene los siguientes elementos principales:
- Un
UIImageView
que mostrará la fuente de vídeo. - Un
UISegmentedControl
que cambiará el modo de enfoque de Automático a Bloqueado. - Cuatro controles
UISlider
que mostrarán y actualizarán el offset, la duración, el ISO y el bias.
Haga lo siguiente para conectar el controlador de vista para el control de exposición manual:
Agregue las siguientes instrucciones using:
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;
Agregue las variables privadas siguientes:
#region Private Variables private NSError Error; private bool Automatic = true; private nfloat ExposureDurationPower = 5; private nfloat ExposureMinimumDuration = 1.0f/1000.0f; #endregion
Agregue las siguientes propiedades calculadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Invalide el método
ViewDidLoad
y agregue el código siguiente: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(); }; }
Invalide el método
ViewDidAppear
y agregue lo siguiente para empezar la grabación cuando se cargue la vista: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 (); } }
Con la cámara en el modo Automático, los controles deslizantes se moverán automáticamente a medida que la cámara ajusta la exposición:
Pulse el segmento Bloqueado y arrastre el control deslizante de bias para ajustar el bias de la exposición automática manualmente:
Pulse el segmento Personalizado y arrastre los controles deslizantes de Duración e ISO para controlar manualmente la exposición:
Detenga la aplicación.
El código anterior ha mostrado cómo supervisar la configuración de exposición cuando la cámara está en modo automático y cómo usar controles deslizantes para controlar la exposición cuando se encuentra en los modos Bloqueado o Personalizado.
Equilibrio manual de blancos
Los controles de balance blancos permiten a los usuarios ajustar el balance de colores en una imagen para que parezcan más realistas. Según la fuente de luz hay una temperatura de color diferente y la configuración de la cámara utilizada para capturar una imagen se debe ajustar para compensar estas diferencias. De nuevo, al permitir que el usuario controle el balance blancos, puede realizar ajustes profesionales que las rutinas automáticas son incapaces de lograr para conseguir efectos artísticos.
Por ejemplo, la luz del día tiene un tono azulado, mientras que las luces fluorescentes de tungsteno tienen un tono amarillo-naranja cálido. (Es confuso, pero los colores «fríos» tienen temperaturas de color más altas que los colores «cálidos». Las temperaturas del color son una medida física, no una medida perceptiva.)
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. La cámara funciona aumentando el color en el espectro opuesto para ajustar las diferencias de color.
La nueva API de exposición de iOS 8 permite a la aplicación tomar el control del proceso y proporcionar un control específico sobre la configuración del balance de blancos de la cámara.
Cómo funciona el balance de blancos
Antes de analizar los detalles del control del balance de blancos en una aplicación de iOS 8. Echemos un vistazo rápido a cómo funciona el balance de blancos:
En el estudio de la percepción del color, el espacio de colores RGB CIE 1931 y el espacio de colores XYZ CIE 1931 son los primeros espacios de color definidos matemáticamente. Fueron creados por la Comisión Internacional de Iluminación (CIE) en 1931.
El gráfico anterior nos muestra todos los colores visibles para el ojo humano, de azul oscuro a verde brillante a rojo brillante. Cualquier punto del diagrama se puede trazar con un valor X e Y, como se muestra en el gráfico anterior.
Como se ve en el gráfico, hay valores X e Y que se pueden trazar en el gráfico que estarían fuera del rango de visión humana y, como resultado, estos colores no se pueden reproducir mediante una cámara.
La curva más pequeña del gráfico anterior se denomina locus planckiano, que expresa la temperatura de color (en grados kelvin), con números más altos en el lado azul (más caliente) y números más bajos en el lado rojo (más frío). Son útiles para situaciones típicas de iluminación.
En condiciones de iluminación mixta, los ajustes de balance de blancos deberán desviarse del locus planckiano para realizar los cambios necesarios. En estas situaciones, el ajuste deberá desplazarse al lado verde o rojo/magenta de la escala de CIE.
Los dispositivos con iOS compensan las conversiones de color aumentando los tonos del color opuesto. Por ejemplo, si una escena tiene demasiado azul, se aumentará la ganancia roja para compensar. Estos valores de ganancia se calibran para dispositivos específicos para que sean dependientes del dispositivo.
Controles de balance de blancos existentes
iOS 7 y las versiones posteriores proporcionaron los siguientes controles de balance de blancos existentes a través de la propiedad WhiteBalanceMode
:
AVCapture WhiteBalance ModeLocked
: muestra la escena una vez y usa esos valores en toda la escena.AVCapture WhiteBalance ModeContinuousAutoExposure
: muestrea la escena continuamente para asegurarse de que está bien equilibrada.
Y la aplicación puede supervisar la propiedad AdjustingWhiteBalance
para ver cuándo se ajusta la exposición.
Nuevos controles de balance de blancos en iOS 8
Además de las características ya proporcionadas por iOS 7 y las versiones posteriores, las siguientes características ahora están disponibles para controlar el balance de blancos en iOS 8:
- Control totalmente manual de las ganancias RGB del dispositivo.
- Obtener, establecer y observar valores clave las ganancias RGB del dispositivo.
- Compatibilidad del balance de blancos mediante una carta gris.
- Rutinas de conversión hacia y desde espacios de colores independientes del dispositivo.
Para implementar las características anteriores, la estructura AVCaptureWhiteBalanceGain
se ha agregado con los miembros siguientes:
RedGain
GreenGain
BlueGain
La ganancia máxima del balance de blancos es actualmente cuatro (4) y puede estar lista desde la propiedad MaxWhiteBalanceGain
. Por lo tanto, el intervalo legal es de uno (1) a MaxWhiteBalanceGain
(4) actualmente.
La propiedad DeviceWhiteBalanceGains
se puede usar para observar los valores actuales. Use SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains
para ajustar las ganancias del balance cuando la cámara está en el modo de balance de blancos bloqueado.
Rutinas de conversión
Las rutinas de conversión se han agregado a iOS 8 para ayudar a convertir espacios de color independientes hacia y desde el dispositivo. Para implementar las rutinas de conversión, la estructura AVCaptureWhiteBalanceChromaticityValues
se ha agregado con los miembros siguientes:
X
: es un valor de 0 a 1.Y
: es un valor de 0 a 1.
También se ha agregado una estructura AVCaptureWhiteBalanceTemperatureAndTintValues
con los siguientes miembros:
Temperature
: es un valor de punto flotante en grados Kelvin.Tint
: es un offset de verde o magenta de 0 a 150 con valores positivos hacia la dirección verde y negativo hacia el magenta.
Utilice los métodos CaptureDevice.GetTemperatureAndTintValues
y CaptureDevice.GetDeviceWhiteBalanceGains
para convertir entre temperatura y tono, cromacidad y espacios de color de ganancia RGB.
Nota:
Las rutinas de conversión son más precisas cuanto más cerca se convierta el valor que se va a convertir es al llocus planckiano.
Compatibilidad con carta gris
Apple usa el término mundo gris para hacer referencia a la compatibilidad con la carta gris integrada en iOS 8. Permite al usuario centrarse en una carta gris física que cubre al menos el 50 % del centro del marco y lo usa para ajustar el balance de blancos. El propósito de la carta gris es lograr un blanco que aparezca neutro.
Esto se puede implementar en una aplicación mediante la solicitud al usuario de colocar una carta gris física delante de la cámara, supervisar la propiedad GrayWorldDeviceWhiteBalanceGains
y esperar hasta que los valores se liquiden.
A continuación, la aplicación bloquearía las ganancias del balance de blancos para el método SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains
mediante los valores de la propiedad GrayWorldDeviceWhiteBalanceGains
para aplicar los cambios.
El dispositivo de captura debe estar bloqueado para la configuración antes de que se pueda realizar un cambio en el balance de blancos.
Ejemplo manual de balance de blancos
Con el código general de instalación de captura de AV en su lugar, se puede agregar un UIViewController
al Storyboard de la aplicación y configurarlo como se indica a continuación:
La vista contiene los siguientes elementos principales:
- Un
UIImageView
que mostrará la fuente de vídeo. - Un
UISegmentedControl
que cambiará el modo de enfoque de Automático a Bloqueado. - Dos controles
UISlider
que mostrarán y actualizarán la temperatura y el tono. - Un
UIButton
se usa para muestrear un espacio de carta gris (mundo gris) y establecer el balance de blancos con esos valores.
Haga lo siguiente para conectar el controlador de vista para el control de balance de blancos manual:
Agregue las siguientes instrucciones using:
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;
Agregue las variables privadas siguientes:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
Agregue las siguientes propiedades calculadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Agregue el siguiente método privado para establecer el nuevo tono y temperatura del balance de blancos:
#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
Invalide el método
ViewDidLoad
y agregue el código siguiente: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 (); } }; }
Invalide el método
ViewDidAppear
y agregue lo siguiente para empezar la grabación cuando se cargue la vista: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 (); } }
Guarde los cambios en el código y ejecute la aplicación.
Con la cámara en el modo Automático, los controles deslizantes se moverán automáticamente a medida que la cámara ajusta el balance de blancos:
Pulse el segmento Bloqueado y arrastre los controles deslizantes de temperatura y tono para ajustar el balance de blancos manualmente:
Con el segmento Bloqueado aún seleccionado, coloque una carta gris física delante de la cámara y pulse el botón carta gris para ajustar el balance de blanco al mundo gris:
Detenga la aplicación.
El código anterior ha mostrado cómo supervisar la configuración del balance de blancos cuando la cámara está en modo automático o usar controles deslizantes para controlar el balance de blancos cuando está en el modo Bloqueado.
Captura entre corchetes
La captura entre corchetes se basa en la configuración de los controles manuales de la cámara presentados anteriormente y permite a la aplicación capturar un momento en el tiempo de varias maneras diferentes.
En pocas palabras, la captura entre corchetes es una ráfaga de imágenes fijas tomadas con una variedad de configuraciones de imagen a imagen.
Con la captura entre corchetes en iOS 8, una aplicación puede preestablecer una serie de controles manuales de la cámara, emitir un único comando y hacer que la escena actual devuelva una serie de imágenes para cada uno de los valores preestablecidos manuales.
Conceptos básicos de captura entre corchetes
De nuevo, la captura entre corchetes es una ráfaga de imágenes fijas tomadas con varias configuraciones de imagen a imagen. Los tipos de captura entre corchetes disponibles son:
- Corchete de exposición automática: donde todas las imágenes tienen una cantidad de bias variado.
- Corchete de exposición manual: donde todas las imágenes tienen una cantidad variada de velocidad de obturación (duración) e ISO.
- Corchete de ráfaga simple: una serie de imágenes fijas tomadas en una sucesión rápida.
Nuevos controles de captura entre corchetes en iOS 8
Todos los comandos de captura entre corchetes se implementan en la clase AVCaptureStillImageOutput
. Use el método CaptureStillImageBracket
para obtener una serie de imágenes con la matriz de configuración especificada.
Se han implementado dos clases nuevas para controlar la configuración:
AVCaptureAutoExposureBracketedStillImageSettings
: tiene una propiedad,ExposureTargetBias
, utilizada para establecer el bias de un corchete de exposición automática.AVCaptureManual
ExposureBracketedStillImageSettings
– Tiene dos propiedades,ExposureDuration
yISO
, usada para establecer la velocidad del obturador e ISO para un soporte de exposición manual.
Normas de los controles de captura entre corchetes
Qué hacer
A continuación se muestra una lista de las cosas que se deben hacer al usar los controles de captura entre corchetes en iOS 8:
- Prepare la aplicación para la situación de captura en el peor de los casos llamando al método
PrepareToCaptureStillImageBracket
. - Supongamos que los búferes de ejemplo van a proceder del mismo grupo compartido.
- Para liberar la memoria asignada por una llamada de preparación anterior, vuelva a llamar a
PrepareToCaptureStillImageBracket
y envíe una matriz de un objeto.
No
A continuación se muestra una lista de las cosas que no se deben hacer al usar los controles de captura entre corchetes en iOS 8:
- No mezcle los tipos de configuración de captura entre corchetes en una sola captura.
- No solicite más de
MaxBracketedCaptureStillImageCount
imágenes en una sola captura.
Detalles de captura entre corchetes
Se deben tener en cuenta los detalles siguientes al trabajar con la captura entre corchetes en iOS 8:
- La configuración entre corchetes invalida temporalmente la configuración
AVCaptureDevice
. - Se omiten los ajustes de estabilización de imágenes y del flash.
- Todas las imágenes deben usar el mismo formato de salida (jpeg, png, etc.)
- La vista previa del vídeo puede quitar fotogramas.
- La captura entre corchetes es compatible con todos los dispositivos compatibles con iOS 8.
Teniendo en cuenta esta información, echemos un vistazo a un ejemplo de uso de captura entre corchetes en iOS 8.
Ejemplo de captura entre corchetes
Con el código general de instalación de captura de AV en su lugar, se puede agregar un UIViewController
al Storyboard de la aplicación y configurarlo como se indica a continuación:
La vista contiene los siguientes elementos principales:
- Un
UIImageView
que mostrará la fuente de vídeo. - Tres
UIImageViews
que mostrarán los resultados de la captura. - Un objeto
UIScrollView
para alojar la fuente de vídeo y las vistas de resultados. - Un
UIButton
se usa para tomar una captura entre corchetes con algunos valores preestablecidos.
Haga lo siguiente para conectar el controlador de vista para la captura entre corchetes:
Agregue las siguientes instrucciones using:
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;
Agregue las variables privadas siguientes:
#region Private Variables private NSError Error; private List<UIImageView> Output = new List<UIImageView>(); private nint OutputIndex = 0; #endregion
Agregue las siguientes propiedades calculadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } #endregion
Agregue el siguiente método privado para crear las vistas de imagen de salida necesarias:
#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
Invalide el método
ViewDidLoad
y agregue el código siguiente: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(); }); }; }
Invalide el método
ViewDidAppear
y agregue el código siguiente: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 (); } }
Guarde los cambios en el código y ejecute la aplicación.
Enmarque una escena y pulse el botón capturar entre corchetes:
Deslice el dedo hacia la derecha a la izquierda para ver las tres imágenes tomadas por la captura entre corchetes:
Detenga la aplicación.
El código anterior ha mostrado cómo configurar y tomar una captura entre corchetes de exposición automática en iOS 8.
Resumen
En este artículo hemos dado una introducción a los nuevos controles manuales de la cámara proporcionados por iOS 8 y hemos tratado los conceptos básicos de qué hacen y cómo funcionan. Hemos dado ejemplos de enfoque manual, exposición manual y balance de blancos manual. Por último, se ha dado un ejemplo de cómo tomar una captura entre corchetes mediante los controles manuales de la cámara descritos anteriormente