Controles manuais de câmera no Xamarin.iOS
Os controles manuais da câmera, fornecidos pelo AVFoundation Framework
no iOS 8, permitem que um aplicativo móvel assuma o controle total sobre a câmera de um dispositivo iOS. Esse nível refinado de controle pode ser usado para criar aplicativos de câmera de nível profissional e fornecer composições de artistas ajustando os parâmetros da câmera enquanto tira uma imagem estática ou vídeo.
Esses controles também podem ser úteis no desenvolvimento de aplicações científicas ou industriais, onde os resultados são menos voltados para a exatidão ou beleza da imagem e são mais voltados para destacar alguma característica ou elemento da imagem que está sendo tirada.
Objetos de captura AVFoundation
Seja gravando vídeos ou imagens estáticas usando a câmera em um dispositivo iOS, o processo usado para capturar essas imagens é basicamente o mesmo. Isso se aplica a aplicativos que usam os controles de câmera automatizados padrão ou aqueles que aproveitam os novos controles manuais de câmera:
A entrada é obtida de um AVCaptureDeviceInput
para um AVCaptureSession
por meio de um AVCaptureConnection
. O resultado é a saída como uma imagem estática ou como um fluxo de vídeo. Todo o processo é controlado por um AVCaptureDevice
.
Controles manuais fornecidos
Usando as novas APIs fornecidas pelo iOS 8, o aplicativo pode assumir o controle dos seguintes recursos da câmera:
- Foco manual – Ao permitir que o usuário final assuma o controle do foco diretamente, um aplicativo pode fornecer mais controle sobre a imagem tirada.
- Exposição manual – Ao fornecer controle manual sobre a exposição, um aplicativo pode fornecer mais liberdade aos usuários e permitir que eles obtenham uma aparência estilizada.
- Balanço de branco manual – O balanço de branco é usado para ajustar a cor de uma imagem, geralmente para torná-la realista. Diferentes fontes de luz têm diferentes temperaturas de cor e as configurações da câmera usadas para capturar uma imagem são ajustadas para compensar essas diferenças. Novamente, ao permitir que o usuário controle sobre o balanço de branco, os usuários podem fazer ajustes que não podem ser feitos automaticamente.
O iOS 8 fornece extensões e aprimoramentos para APIs iOS existentes para fornecer esse controle refinado sobre o processo de captura de imagem.
Requisitos
Os itens a seguir são necessários para concluir as etapas apresentadas neste artigo:
- Xcode 7+ e iOS 8 ou mais recente – As APIs Xcode 7 e iOS 8 ou mais recentes da Apple precisam ser instaladas e configuradas no computador do desenvolvedor.
- Visual Studio para Mac – A versão mais recente do Visual Studio para Mac deve ser instalada e configurada no dispositivo do usuário.
- Dispositivo iOS 8 – Um dispositivo iOS executando a versão mais recente do iOS 8. Os recursos da câmera não podem ser testados no Simulador do iOS.
Configuração geral de captura AV
Ao gravar vídeo em um dispositivo iOS, há algum código de configuração geral que é sempre necessário. Esta seção abordará a configuração mínima necessária para gravar vídeo da câmera do dispositivo iOS e exibir esse vídeo em tempo real em um UIImageView
arquivo .
Delegado de buffer de exemplo de saída
Uma das primeiras coisas necessárias será um delegado para monitorar o buffer de Saída de Exemplo e exibir uma imagem capturada do buffer para a UIImageView
na interface do usuário do aplicativo.
A rotina a seguir monitorará o Buffer de Exemplo e atualizará a interface do usuário:
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
}
}
Com essa rotina em vigor, o AppDelegate
pode ser modificado para abrir uma sessão de captura AV para gravar um feed de vídeo ao vivo.
Criando uma sessão de captura AV
A sessão de captura AV é usada para controlar a gravação de vídeo ao vivo da câmera do dispositivo iOS e é necessária para colocar o vídeo em um aplicativo iOS. Como o ManualCameraControl
aplicativo de exemplo está usando a sessão de captura em vários locais diferentes, ele será configurado e AppDelegate
disponibilizado para todo o aplicativo.
Faça o seguinte para modificar o aplicativo AppDelegate
e adicionar o código necessário:
Clique duas vezes no
AppDelegate.cs
arquivo no Gerenciador de Soluções para abri-lo para edição.Adicione o seguinte usando as instruções na parte superior do arquivo :
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;
Adicione as seguintes variáveis privadas e propriedades computadas à
AppDelegate
classe:#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
Substitua o método concluído e altere-o para:
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; }
Salve as alterações no arquivo.
Com esse código em vigor, os controles manuais da câmera podem ser facilmente implementados para experimentação e teste.
Foco manual
Ao permitir que o usuário final assuma o controle do foco diretamente, um aplicativo pode fornecer mais controle artístico sobre a imagem tirada.
Por exemplo, um fotógrafo profissional pode suavizar o foco de uma imagem para obter um efeito Bokeh. Ou crie um Efeito de Atração de Foco.
Para cientistas ou um escritor de aplicações médicas, o aplicativo pode querer mover programaticamente a lente para experimentos. De qualquer forma, a nova API permite que o usuário final ou o aplicativo assuma o controle do foco no momento em que a imagem é tirada.
Como funciona o foco
Antes de discutir os detalhes do controle de foco em um aplicativo IOS 8. Vamos dar uma olhada rápida em como o foco funciona em um dispositivo iOS:
A luz entra na lente da câmera no dispositivo iOS e é focada em um sensor de imagem. A distância da lente do sensor controla onde está o ponto focal (a área onde a imagem aparecerá mais nítida), em relação ao sensor. Quanto mais longe a lente estiver do sensor, os objetos distantes parecem mais nítidos e os objetos mais próximos parecem mais nítidos.
Em um dispositivo iOS, a lente é movida para mais perto ou mais longe do sensor por ímãs e molas. Como resultado, o posicionamento exato da lente é impossível, pois varia de dispositivo para dispositivo e pode ser afetado por parâmetros como a orientação do dispositivo ou a idade do dispositivo e da mola.
Termos de foco importantes
Ao lidar com foco, existem alguns termos com os quais o desenvolvedor deve estar familiarizado:
- Profundidade de campo – A distância entre os objetos mais próximos e mais distantes em foco.
- Macro - Esta é a extremidade próxima do espectro de foco e é a distância mais próxima na qual a lente pode focar.
- Infinito – Esta é a extremidade mais distante do espectro de foco e é a distância mais distante na qual a lente pode focar.
- Distância hiperfocal – Este é o ponto no espectro de foco em que o objeto mais distante no quadro está na extremidade do foco. Em outras palavras, esta é a posição focal que maximiza a profundidade de campo.
- Posição da lente - Isso é o que controla todos os outros termos acima. Esta é a distância da lente do sensor e, portanto, do controlador de foco.
Com esses termos e conhecimento em mente, os novos controles de foco manual podem ser implementados com sucesso em um aplicativo iOS 8.
Controles de foco existentes
O iOS 7 e versões anteriores forneciam controles de foco existentes por meio da FocusMode
propriedade como:
AVCaptureFocusModeLocked
– O foco está travado em um único ponto de foco.AVCaptureFocusModeAutoFocus
– A câmera varre a lente por todos os pontos focais até encontrar um foco nítido e depois permanece lá.AVCaptureFocusModeContinuousAutoFocus
– A câmera foca novamente sempre que detecta uma condição de desfoque.
Os controles existentes também forneceram um ponto de interesse configurável por meio daFocusPointOfInterest
propriedade, para que o usuário possa tocar para focar em uma área específica. O aplicativo também pode rastrear o movimento da lente monitorando a IsAdjustingFocus
propriedade.
Além disso, a restrição de AutoFocusRangeRestriction
alcance foi fornecida pela propriedade como:
AVCaptureAutoFocusRangeRestrictionNear
– Restringe o foco automático a profundidades próximas. Útil em situações como a leitura de um QR Code ou código de barras.AVCaptureAutoFocusRangeRestrictionFar
– Restringe o foco automático a profundidades distantes. Útil em situações em que objetos que são conhecidos por serem irrelevantes estão no campo de visão (por exemplo, uma moldura de janela).
Finalmente, há a SmoothAutoFocus
propriedade que desacelera o algoritmo de foco automático e o percorre em incrementos menores para evitar artefatos móveis durante a gravação de vídeo.
Novos controles de foco no iOS 8
Além dos recursos já fornecidos pelo iOS 7 e superior, os seguintes recursos agora estão disponíveis para controlar o foco no iOS 8:
- Controle manual total da posição da lente ao travar o foco.
- Observação de valor-chave da posição da lente em qualquer modo de foco.
Para implementar os recursos acima, a AVCaptureDevice
classe foi modificada para incluir uma propriedade somente LensPosition
leitura usada para obter a posição atual da lente da câmera.
Para assumir o controle manual da posição da lente, o dispositivo de captura deve estar no modo de foco bloqueado. Exemplo:
CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;
O SetFocusModeLocked
método do dispositivo de captura é usado para ajustar a posição da lente da câmera. Uma rotina de retorno de chamada opcional pode ser fornecida para obter notificação quando a alteração entrar em vigor. Exemplo:
ThisApp.CaptureDevice.LockForConfiguration(out Error);
ThisApp.CaptureDevice.SetFocusModeLocked(Position.Value,null);
ThisApp.CaptureDevice.UnlockForConfiguration();
Como visto no código acima, o dispositivo de captura deve ser bloqueado para configuração antes que uma alteração na posição da lente possa ser feita. Os valores válidos de Posição da lente estão entre 0,0 e 1,0.
Exemplo de foco manual
Com o código de Configuração Geral de Captura AV em vigor, um UIViewController
pode ser adicionado ao Storyboard do aplicativo e configurado da seguinte maneira:
A visualização contém os seguintes elementos principais:
- A
UIImageView
que exibirá o feed de vídeo. - A
UISegmentedControl
que mudará o Modo de Foco de Automático para Bloqueado. - A
UISlider
que mostrará e atualizará a posição atual da lente.
Faça o seguinte para conectar o controlador de exibição para Controle de foco manual:
Adicione as seguintes instruções 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;
Adicione as seguintes variáveis privadas:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
Adicione as seguintes propriedades computadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Substitua o
ViewDidLoad
método e adicione o seguinte código: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(); }; }
Substitua o
ViewDidAppear
método e adicione o seguinte para iniciar a gravação quando a exibição for carregada: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 (); } }
Com a câmera no modo Automático, o controle deslizante se moverá automaticamente à medida que a câmera ajusta o foco:
Toque no segmento bloqueado e arraste o controle deslizante de posição para ajustar a posição da lente manualmente:
Pare o aplicativo.
O código acima mostrou como monitorar a posição da lente quando a câmera está no modo Automático ou usar um controle deslizante para controlar a posição da lente quando ela está no modo Bloqueado.
Exposição manual
A exposição refere-se ao brilho de uma imagem em relação ao brilho da fonte e é determinada pela quantidade de luz que atinge o sensor, por quanto tempo e pelo nível de ganho do sensor (mapeamento ISO). Ao fornecer controle manual sobre a exposição, um aplicativo pode fornecer mais liberdade ao usuário final e permitir que ele obtenha uma aparência estilizada.
Usando os controles de exposição manual, o usuário pode tirar uma imagem de irrealisticamente clara para escura e temperamental:
Novamente, isso pode ser feito automaticamente usando o controle programático para aplicações científicas ou por meio de controles manuais fornecidos pela interface do usuário dos aplicativos. De qualquer forma, as novas APIs de exposição do iOS 8 fornecem controle refinado sobre as configurações de exposição da câmera.
Como funciona a exposição
Antes de discutir os detalhes do controle da exposição em um aplicativo IOS 8. Vamos dar uma olhada rápida em como funciona a exposição:
Os três elementos básicos que se unem para controlar a exposição são:
- Velocidade do obturador – Este é o período de tempo que o obturador está aberto para permitir que a luz entre no sensor da câmera. Quanto menor o tempo que o obturador está aberto, menos luz é deixada entrar e mais nítida é a imagem (menos desfoque de movimento). Quanto mais tempo o obturador estiver aberto, mais luz será deixada entrar e mais desfoque de movimento ocorrerá.
- Mapeamento ISO – Este é um termo emprestado da fotografia de filme e refere-se à sensibilidade dos produtos químicos do filme à luz. Valores ISO baixos no filme têm menos granulação e reprodução de cores mais finas; valores ISO baixos em sensores digitais têm menos ruído do sensor, mas menos brilho. Quanto maior o valor ISO, mais brilhante é a imagem, mas com mais ruído do sensor. "ISO" em um sensor digital é uma medida de ganho eletrônico, não um recurso físico.
- Abertura da lente – Este é o tamanho da abertura da lente. Em todos os dispositivos iOS, a abertura da lente é fixa, portanto, os únicos dois valores que podem ser usados para ajustar a exposição são a velocidade do obturador e o ISO.
Como funciona a exposição automática contínua
Antes de aprender como funciona a exposição manual, é uma boa ideia entender como a exposição automática contínua funciona em um dispositivo iOS.
O primeiro é o Bloco de Exposição Automática, ele tem o trabalho de calcular a exposição ideal e está continuamente sendo alimentado com Estatísticas de Medição. Ele usa essas informações para calcular a combinação ideal de ISO e velocidade do obturador para deixar a cena bem iluminada. Este ciclo é conhecido como AE Loop.
Como funciona a exposição bloqueada
A seguir, vamos examinar como a exposição bloqueada funciona em dispositivos iOS.
Novamente, você tem o Bloco de exposição automática que está tentando calcular os valores ideais de iOS e Duração. No entanto, neste modo, o Bloco AE é desconectado do mecanismo de Estatísticas de Medição.
Controles de exposição existentes
iOS 7 e superior, fornecem os seguintes controles de exposição existentes por meio da ExposureMode
propriedade:
AVCaptureExposureModeLocked
– Amostra da cena uma vez e usa esses valores em toda a cena.AVCaptureExposureModeContinuousAutoExposure
– Amostras da cena continuamente para garantir que esteja bem iluminada.
O ExposurePointOfInterest
pode ser usado para tocar para expor a cena selecionando um objeto de destino para expor, e o aplicativo pode monitorar a propriedade para ver quando a AdjustingExposure
exposição está sendo ajustada.
Novos controles de exposição no iOS 8
Além dos recursos já fornecidos pelo iOS 7 e superior, os seguintes recursos agora estão disponíveis para controlar a exposição no iOS 8:
- Exposição personalizada totalmente manual.
- Obter, definir e valor-chave Observe o IOS e a velocidade do obturador (duração).
Para implementar os recursos acima, um novo AVCaptureExposureModeCustom
modo foi adicionado. Quando a câmera está no modo personalizado, o seguinte código pode ser usado para ajustar a duração da exposição e o ISO:
CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.LockExposure(DurationValue,ISOValue,null);
CaptureDevice.UnlockForConfiguration();
Nos modos Automático e Bloqueado, o aplicativo pode ajustar o Bias da rotina de exposição automática usando o seguinte código:
CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.SetExposureTargetBias(Value,null);
CaptureDevice.UnlockForConfiguration();
Os intervalos de configuração mínimo e máximo dependem do dispositivo em que o aplicativo está sendo executado, portanto, eles nunca devem ser codificados. Em vez disso, use as seguintes propriedades para obter os intervalos de valores mínimo e máximo:
CaptureDevice.MinExposureTargetBias
CaptureDevice.MaxExposureTargetBias
CaptureDevice.ActiveFormat.MinISO
CaptureDevice.ActiveFormat.MaxISO
CaptureDevice.ActiveFormat.MinExposureDuration
CaptureDevice.ActiveFormat.MaxExposureDuration
Como visto no código acima, o dispositivo de captura deve ser bloqueado para configuração antes que uma alteração na exposição possa ser feita.
Exposição manual Example
Com o código de Configuração Geral de Captura AV em vigor, um UIViewController
pode ser adicionado ao Storyboard do aplicativo e configurado da seguinte maneira:
A visualização contém os seguintes elementos principais:
- A
UIImageView
que exibirá o feed de vídeo. - A
UISegmentedControl
que mudará o Modo de Foco de Automático para Bloqueado. - Quatro
UISlider
controles que mostrarão e atualizarão o Deslocamento, Duração, ISO e Desvio.
Faça o seguinte para conectar o controlador de exibição para Controle de exposição manual:
Adicione as seguintes instruções 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;
Adicione as seguintes variáveis privadas:
#region Private Variables private NSError Error; private bool Automatic = true; private nfloat ExposureDurationPower = 5; private nfloat ExposureMinimumDuration = 1.0f/1000.0f; #endregion
Adicione as seguintes propriedades computadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Substitua o
ViewDidLoad
método e adicione o seguinte código: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(); }; }
Substitua o
ViewDidAppear
método e adicione o seguinte para iniciar a gravação quando a exibição for carregada: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 (); } }
Com a câmera no modo Automático, os controles deslizantes se moverão automaticamente à medida que a câmera ajusta a exposição:
Toque no segmento Bloqueado e arraste o controle deslizante Desvio para ajustar o desvio da exposição automática manualmente:
Toque no segmento Personalizado e arraste os controles deslizantes Duração e ISO para controlar manualmente a exposição:
Pare o aplicativo.
O código acima mostrou como monitorar as configurações de exposição quando a câmera está no modo Automático e como usar controles deslizantes para controlar a exposição quando ela está nos modos Bloqueado ou Personalizado.
Balanço de branco manual
Os controles de balanço de branco permitem que os usuários ajustem o equilíbrio do colosr em uma imagem para torná-los mais realistas. Diferentes fontes de luz têm diferentes temperaturas de cor e as configurações da câmera usadas para capturar uma imagem devem ser ajustadas para compensar essas diferenças. Novamente, ao permitir que o usuário controle sobre o balanço de branco, ele pode fazer ajustes profissionais que as rotinas automáticas são incapazes de obter efeitos artísticos.
Por exemplo, a luz do dia tem um tom azulado, enquanto as luzes incandescentes de tungstênio têm uma tonalidade amarelo-laranja mais quente. (Confusamente, as cores "frias" têm temperaturas de cor mais altas do que as cores "quentes". As temperaturas de cor são uma medida física, não perceptiva.)
A mente humana é muito boa em compensar as diferenças na temperatura da cor, mas isso é algo que uma câmera não pode fazer. A câmera funciona aumentando a cor no espectro oposto para ajustar as diferenças de cor.
A nova API de exposição do iOS 8 permite que o aplicativo assuma o controle do processo e forneça controle refinado sobre as configurações de balanço de branco da câmera.
Como funciona o balanço de branco
Antes de discutir os detalhes do controle do balanço de branco em um aplicativo IOS 8. Vamos dar uma olhada rápida em como funciona o balanço de branco:
No estudo da percepção de cores, o espaço de cores CIE 1931 RGB e o espaço de cores CIE 1931 XYZ são os primeiros espaços de cores matematicamente definidos. Eles foram criados pela Comissão Internacional de Iluminação (CIE) em 1931.
O gráfico acima nos mostra todas as cores visíveis ao olho humano, do azul profundo ao verde brilhante e ao vermelho brilhante. Qualquer ponto no diagrama pode ser plotado com um valor X e Y, conforme mostrado no gráfico acima.
Como visível no gráfico, existem valores X e Y que podem ser plotados no gráfico que estariam fora do alcance da visão humana e, como resultado, essas cores não podem ser reproduzidas por uma câmera.
A curva menor no gráfico acima é chamada de locus planckiano, que expressa a temperatura da cor (em graus kelvin), com números mais altos no lado azul (mais quente) e números mais baixos no lado vermelho (mais frio). Eles são úteis para situações típicas de iluminação.
Em condições de iluminação mistas, os ajustes do balanço de branco precisarão se desviar do Locus Planckiano para fazer as alterações necessárias. Nessas situações, o ajuste precisará ser deslocado para o lado verde ou vermelho/magenta da escala CIE.
Os dispositivos iOS compensam as projeções de cores aumentando o ganho de cor oposta. Por exemplo, se uma cena tiver muito azul, o ganho de vermelho será aumentado para compensar. Esses valores de ganho são calibrados para dispositivos específicos, portanto, dependem do dispositivo.
Controles de balanço de branco existentes
O iOS 7 e superior forneciam os seguintes controles de Balanço de Branco existentes por meio WhiteBalanceMode
da propriedade:
AVCapture WhiteBalance ModeLocked
– Faz uma amostra da cena uma vez e usa esses valores em toda a cena.AVCapture WhiteBalance ModeContinuousAutoExposure
– Amostras da cena continuamente para garantir que ela esteja bem equilibrada.
E o aplicativo pode monitorar a propriedade para ver quando a AdjustingWhiteBalance
exposição está sendo ajustada.
Novos controles de balanço de branco no iOS 8
Além dos recursos já fornecidos pelo iOS 7 e superior, os seguintes recursos agora estão disponíveis para controlar o Balanço de Branco no iOS 8:
- Controle totalmente manual dos ganhos RGB do dispositivo.
- Obter, definir e valor-chave Observe os ganhos RGB do dispositivo.
- Suporte para balanço de branco usando um cartão cinza.
- Rotinas de conversão de e para espaços de cores independentes do dispositivo.
Para implementar os recursos acima, a AVCaptureWhiteBalanceGain
estrutura foi adicionada com os seguintes membros:
RedGain
GreenGain
BlueGain
O ganho máximo de balanço de branco é atualmente de quatro (4) e pode ser obtido na MaxWhiteBalanceGain
propriedade. Portanto, o intervalo legal é de um (1) a MaxWhiteBalanceGain
(4) atualmente.
A DeviceWhiteBalanceGains
propriedade pode ser usada para observar os valores atuais. Use SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains
para ajustar os ganhos de equilíbrio quando a câmera estiver no modo de balanço de branco bloqueado.
Rotinas de conversão
Rotinas de conversão foram adicionadas ao iOS 8 para ajudar na conversão de e para espaços de cores independentes do dispositivo. Para implementar as rotinas de conversão, a AVCaptureWhiteBalanceChromaticityValues
estrutura foi adicionada com os seguintes membros:
X
- é um valor de 0 a 1.Y
- é um valor de 0 a 1.
Uma AVCaptureWhiteBalanceTemperatureAndTintValues
estrutura também foi adicionada com os seguintes membros:
Temperature
- é um valor de ponto flutuante em graus Kelvin.Tint
- é um deslocamento de verde ou magenta de 0 a 150 com valores positivos para a direção verde e negativos para no magenta.
Use os CaptureDevice.GetTemperatureAndTintValues
métodos e os CaptureDevice.GetDeviceWhiteBalanceGains
métodos para converter entre temperatura e tonalidade, cromaticidade e espaços de cores de ganho RGB.
Observação
As rotinas de conversão são mais precisas quanto mais próximo o valor a ser convertido estiver do locus de Planck.
Suporte para cartão cinza
A Apple usa o termo Gray World para se referir ao suporte a Gray Card integrado ao iOS 8. Ele permite que o usuário se concentre em um cartão cinza físico que cubra pelo menos 50% do centro do quadro e o use para ajustar o balanço de branco. O objetivo do Cartão Cinza é obter um branco que pareça neutro.
Isso pode ser implementado em um aplicativo solicitando que o usuário coloque um cartão cinza físico na frente da câmera, monitorando a GrayWorldDeviceWhiteBalanceGains
propriedade e aguardando até que os valores se estabilizem.
Em seguida, o aplicativo bloquearia os ganhos de Balanço de Branco para o SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains
método usando os valores da GrayWorldDeviceWhiteBalanceGains
propriedade para aplicar as alterações.
O dispositivo de captura deve ser bloqueado para configuração antes que uma alteração no balanço de branco possa ser feita.
Exemplo de balanço de branco manual
Com o código de Configuração Geral de Captura AV em vigor, um UIViewController
pode ser adicionado ao Storyboard do aplicativo e configurado da seguinte maneira:
A visualização contém os seguintes elementos principais:
- A
UIImageView
que exibirá o feed de vídeo. - A
UISegmentedControl
que mudará o Modo de Foco de Automático para Bloqueado. - Dois
UISlider
controles que mostrarão e atualizarão a temperatura e a tonalidade. - A
UIButton
usado para amostrar um espaço de Cartão cinza (Mundo cinza) e definir o Balanço de branco usando esses valores.
Faça o seguinte para conectar o controlador de exibição para o controle manual de balanço de branco:
Adicione as seguintes instruções 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;
Adicione as seguintes variáveis privadas:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
Adicione as seguintes propriedades computadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Adicione o seguinte método privado para definir o novo balanço de branco Temperatura e Tonalidade:
#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
Substitua o
ViewDidLoad
método e adicione o seguinte código: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 (); } }; }
Substitua o
ViewDidAppear
método e adicione o seguinte para iniciar a gravação quando a exibição for carregada: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 (); } }
Salve as alterações no código e execute o aplicativo.
Com a câmera no modo Automático, os controles deslizantes se moverão automaticamente à medida que a câmera ajusta o balanço de branco:
Toque no segmento Bloqueado e arraste os controles deslizantes Temp e Tint para ajustar o balanço de branco manualmente:
Com o segmento Bloqueado ainda selecionado, coloque um cartão cinza físico na frente da câmera e toque no botão Cartão cinza para ajustar o balanço de branco para o Mundo Cinza:
Pare o aplicativo.
O código acima mostrou como monitorar as configurações de balanço de branco quando a câmera está no modo Automático ou usar controles deslizantes para controlar o balanço de branco quando está no modo Bloqueado.
Captura entre colchetes
A Captura Agrupada é baseada nas configurações dos Controles Manuais da Câmera apresentados acima e permite que o aplicativo capture um momento no tempo, de várias maneiras diferentes.
Simplificando, a captura entre colchetes é uma sequência de imagens estáticas tiradas com uma variedade de configurações de imagem para imagem.
Usando a Captura entre colchetes no iOS 8, um aplicativo pode predefinir uma série de controles manuais da câmera, emitir um único comando e fazer com que a cena atual retorne uma série de imagens para cada uma das predefinições manuais.
Noções básicas de captura entre colchetes
Novamente, a captura entre colchetes é uma sequência de imagens estáticas tiradas com configurações variadas de imagem para imagem. Os tipos de Captura entre colchetes disponíveis são:
- Suporte de exposição automática – onde todas as imagens têm uma quantidade variada de polarização.
- Suporte de exposição manual – onde todas as imagens têm uma velocidade do obturador (duração) e quantidade ISO variadas.
- Suporte de rajada simples – Uma série de imagens estáticas tiradas em rápida sucessão.
Novos controles de captura entre colchetes no iOS 8
Todos os comandos de Captura entre colchetes são implementados na AVCaptureStillImageOutput
classe. Use o CaptureStillImageBracket
método para obter uma série de imagens com a matriz de configurações fornecida.
Duas novas classes foram implementadas para lidar com as configurações:
AVCaptureAutoExposureBracketedStillImageSettings
– Tem uma propriedade,ExposureTargetBias
, usada para definir o viés para um suporte de exposição automática.AVCaptureManual
ExposureBracketedStillImageSettings
– Tem duas propriedades,ExposureDuration
eISO
, usado para definir a velocidade do obturador e ISO para um suporte de exposição manual.
Controles de captura entre colchetes O que fazer e o que não fazer
Fazer
Veja a seguir uma lista de coisas que devem ser feitas ao usar os controles de captura entre colchetes no iOS 8:
- Prepare o aplicativo para a pior situação de captura chamando o
PrepareToCaptureStillImageBracket
método. - Suponha que os buffers de exemplo venham do mesmo pool compartilhado.
- Para liberar a memória que foi alocada por uma chamada de preparação anterior, chame
PrepareToCaptureStillImageBracket
novamente e envie uma matriz de um objeto.
O que não fazer
Veja a seguir uma lista de coisas que não devem ser feitas ao usar os controles de captura entre colchetes no iOS 8:
- Não misture os tipos de configurações de Captura entre colchetes em uma única captura.
- Não solicite mais do que
MaxBracketedCaptureStillImageCount
imagens em uma única captura.
Detalhes da captura entre colchetes
Os seguintes detalhes devem ser levados em consideração ao trabalhar com a Captura entre colchetes no iOS 8:
- As configurações entre colchetes substituem temporariamente as
AVCaptureDevice
configurações. - As configurações de estabilização de flash e imagem estática são ignoradas.
- Todas as imagens devem usar o mesmo formato de saída (jpeg, png, etc.)
- A visualização do vídeo pode perder quadros.
- A Captura entre colchetes é compatível com todos os dispositivos compatíveis com o iOS 8.
Com essas informações em mente, vamos dar uma olhada em um exemplo de uso da Captura entre colchetes no iOS 8.
Exemplo de captura de colchetes
Com o código de Configuração Geral de Captura AV em vigor, um UIViewController
pode ser adicionado ao Storyboard do aplicativo e configurado da seguinte maneira:
A visualização contém os seguintes elementos principais:
- A
UIImageView
que exibirá o feed de vídeo. - Três
UIImageViews
que exibirão os resultados da captura. - A
UIScrollView
para abrigar o feed de vídeo e as visualizações dos resultados. - Costumava
UIButton
fazer uma captura entre colchetes com algumas configurações predefinidas.
Faça o seguinte para conectar o controlador de exibição para Captura entre colchetes:
Adicione as seguintes instruções 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;
Adicione as seguintes variáveis privadas:
#region Private Variables private NSError Error; private List<UIImageView> Output = new List<UIImageView>(); private nint OutputIndex = 0; #endregion
Adicione as seguintes propriedades computadas:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } #endregion
Adicione o seguinte método privado para criar as exibições de imagem de saída necessárias:
#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
Substitua o
ViewDidLoad
método e adicione o seguinte código: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(); }); }; }
Substitua o
ViewDidAppear
método e adicione o seguinte código: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 (); } }
Salve as alterações no código e execute o aplicativo.
Enquadre uma cena e toque no botão Capturar colchete:
Deslize da direita para a esquerda para ver as três imagens tiradas pela Captura entre colchetes:
Pare o aplicativo.
O código acima mostrou como configurar e fazer uma captura com suporte de exposição automática no iOS 8.
Resumo
Neste artigo, abordamos uma introdução aos novos controles manuais de câmera fornecidos pelo iOS 8 e abordamos os fundamentos do que eles fazem e como funcionam. Demos exemplos de Foco Manual, Exposição Manual e Balanço de Branco Manual. Por fim, demos um exemplo de captura entre colchetes usando os controles manuais de câmera discutidos anteriormente