Controlli manuali della fotocamera in Xamarin.iOS
I controlli della fotocamera manuale, forniti da AVFoundation Framework
in iOS 8, consentono a un'applicazione mobile di assumere il controllo completo sulla fotocamera di un dispositivo iOS. Questo livello di controllo con granularità fine può essere utilizzato per creare applicazioni di fotocamera a livello professionale e fornire composizioni dell'artista modificando i parametri della fotocamera durante l'acquisizione di un'immagine o un video.
Questi controlli possono essere utili anche quando si sviluppano applicazioni scientifiche o industriali, in cui i risultati sono meno orientati verso la correttezza o la bellezza dell'immagine, e sono maggiormente orientati verso l'evidenziazione di alcune caratteristiche o elementi dell'immagine scattata.
Oggetti di acquisizione AVFoundation
Se si acquisiscono video o immagini ancora usando la fotocamera in un dispositivo iOS, il processo usato per acquisire tali immagini è in gran parte lo stesso. Ciò vale per le applicazioni che usano i controlli della fotocamera automatizzati predefiniti o quelli che sfruttano i nuovi controlli della fotocamera manuale:
L'input viene ricavato da un AVCaptureDeviceInput
oggetto in un AVCaptureSession
tramite un oggetto AVCaptureConnection
. Il risultato è l'output come immagine ancora o come flusso video. L'intero processo è controllato da un oggetto AVCaptureDevice
.
Controlli manuali forniti
Usando le nuove API fornite da iOS 8, l'applicazione può assumere il controllo delle funzionalità della fotocamera seguenti:
- Stato attivo manuale: consentendo all'utente finale di assumere direttamente il controllo dello stato attivo, un'applicazione può fornire un maggiore controllo sull'immagine acquisita.
- Esposizione manuale: fornendo un controllo manuale sull'esposizione, un'applicazione può offrire maggiore libertà agli utenti e consentire loro di ottenere un aspetto stilizzato.
- Bilanciamento del bianco manuale: il bilanciamento del bianco viene usato per regolare il colore in un'immagine, spesso per renderlo realistico. Diverse fonti di luce hanno temperature di colore diverse e le impostazioni della fotocamera usate per acquisire un'immagine vengono regolate per compensare queste differenze. Anche in questo caso, consentendo all'utente di controllare il bilanciamento del bianco, gli utenti possono apportare modifiche che non possono essere eseguite automaticamente.
iOS 8 offre estensioni e miglioramenti alle API iOS esistenti per fornire questo controllo granulare sul processo di acquisizione delle immagini.
Requisiti
Per completare i passaggi presentati in questo articolo, è necessario quanto segue:
- Xcode 7+ e iOS 8 o versione successiva: le API Xcode 7 e iOS 8 o successive di Apple devono essere installate e configurate nel computer dello sviluppatore.
- Visual Studio per Mac: la versione più recente di Visual Studio per Mac deve essere installata e configurata nel dispositivo utente.
- Dispositivo iOS 8: un dispositivo iOS che esegue la versione più recente di iOS 8. Le funzionalità della fotocamera non possono essere testate nel simulatore iOS.
Configurazione generale dell'acquisizione AV
Quando si registrano video in un dispositivo iOS, è sempre necessario un codice di configurazione generale. Questa sezione illustra la configurazione minima necessaria per registrare video dalla fotocamera del dispositivo iOS e visualizzare il video in tempo reale in un oggetto UIImageView
.
Delegato del buffer di esempio di output
Uno dei primi elementi necessari sarà un delegato per monitorare il buffer di output di esempio e visualizzare un'immagine afferrata dal buffer a un UIImageView
nell'interfaccia utente dell'applicazione.
La routine seguente monitorerà il buffer di esempio e aggiornerà l'interfaccia utente:
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 questa routine sul posto, AppDelegate
può essere modificato per aprire una sessione di acquisizione AV per registrare un feed video live.
Creazione di una sessione di acquisizione AV
La sessione di acquisizione AV viene usata per controllare la registrazione di video live dalla fotocamera del dispositivo iOS ed è necessaria per ottenere video in un'applicazione iOS. Poiché l'applicazione di esempio ManualCameraControl
usa la sessione di acquisizione in diverse posizioni, verrà configurata in AppDelegate
e resa disponibile per l'intera applicazione.
Eseguire le operazioni seguenti per modificare l'applicazione AppDelegate
e aggiungere il codice necessario:
Fare doppio clic sul
AppDelegate.cs
file nel Esplora soluzioni per aprirlo per la modifica.Aggiungere le istruzioni using seguenti all'inizio del file :
using System; using Foundation; using UIKit; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using AVFoundation; using CoreVideo; using CoreMedia; using CoreGraphics; using CoreFoundation;
Aggiungere le variabili private e le proprietà calcolate seguenti alla
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
Eseguire l'override del metodo completato e modificarlo in:
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; }
Salvare le modifiche apportate al file.
Con questo codice sul posto, i controlli della fotocamera manuale possono essere facilmente implementati per la sperimentazione e il test.
Stato attivo manuale
Consentendo all'utente finale di assumere direttamente il controllo dello stato attivo, un'applicazione può fornire un controllo più artistico sull'immagine acquisita.
Ad esempio, un fotografo professionista può ammorbidire lo stato attivo di un'immagine per ottenere un effetto Bokeh. In alternativa, creare un effetto di pull dello stato attivo.
Per gli scienziati o uno scrittore di applicazioni mediche, l'applicazione potrebbe voler spostare a livello di codice l'obiettivo per gli esperimenti. In entrambi i casi, la nuova API consente all'utente finale o all'applicazione di assumere il controllo dello stato attivo al momento in cui viene acquisita l'immagine.
Funzionamento dello stato attivo
Prima di discutere i dettagli del controllo dello stato attivo in un'applicazione IOS 8. Di seguito viene illustrato il funzionamento dello stato attivo in un dispositivo iOS:
La luce entra nell'obiettivo della fotocamera sul dispositivo iOS e si concentra su un sensore di immagine. La distanza dell'obiettivo dal sensore controlla dove il punto focale (l'area in cui l'immagine apparirà più nitida) è, in relazione al sensore. Più lontano l'obiettivo è dal sensore, gli oggetti distanza sembrano più nitidi e più vicini, gli oggetti vicini sembrano più nitidi.
In un dispositivo iOS, l'obiettivo viene spostato più vicino, o più lontano, dal sensore da magneti e sorgenti. Di conseguenza, il posizionamento esatto dell'obiettivo è impossibile, in quanto varia da dispositivo a dispositivo e può essere influenzato da parametri come l'orientamento del dispositivo o l'età del dispositivo e primavera.
Termini importanti per lo stato attivo
Quando si lavora con lo stato attivo, ci sono alcuni termini che lo sviluppatore deve avere familiarità con:
- Profondità di Field : distanza tra gli oggetti più vicini e più lontani nello stato attivo.
- Macro - Si tratta della fine quasi dello spettro dello stato attivo ed è la distanza più vicina in cui l'obiettivo può concentrarsi.
- Infinity - Questa è la fine dello spettro dello stato attivo ed è la distanza più lontana in cui l'obiettivo può concentrarsi.
- Distanza iperfocale: si tratta del punto nello spettro dello stato attivo in cui l'oggetto più lontano nella cornice si trova solo all'estremità dello stato attivo. In altre parole, questa è la posizione focale che ottimizza la profondità del campo.
- Posizione lente : questo è ciò che controlla tutti gli altri termini precedenti. Questa è la distanza dell'obiettivo dal sensore e quindi il controller dello stato attivo.
Tenendo presenti questi termini e conoscenze, i nuovi controlli dello stato attivo manuale possono essere implementati correttamente in un'applicazione iOS 8.
Controlli dello stato attivo esistenti
iOS 7 e versioni precedenti, hanno fornito controlli dello stato attivo esistenti tramite FocusMode
la proprietà come:
AVCaptureFocusModeLocked
– Lo stato attivo è bloccato in un singolo punto attivo.AVCaptureFocusModeAutoFocus
– La fotocamera spazza l'obiettivo attraverso tutti i punti focali fino a quando non trova lo stato attivo tagliente e poi rimane lì.AVCaptureFocusModeContinuousAutoFocus
– La fotocamera viene rifocus ogni volta che rileva una condizione di messa a fuoco insufficiente.
I controlli esistenti hanno fornito anche un punto di interesse impostabile tramite laFocusPointOfInterest
proprietà , in modo che l'utente possa toccare per concentrarsi su una determinata area. L'applicazione può anche tenere traccia del movimento dell'obiettivo monitorando la IsAdjustingFocus
proprietà.
Inoltre, la restrizione dell'intervallo AutoFocusRangeRestriction
è stata fornita dalla proprietà come:
AVCaptureAutoFocusRangeRestrictionNear
– Limita l'autofocus alle profondità vicine. Utile in situazioni come l'analisi di un codice a matrice o un codice a barre.AVCaptureAutoFocusRangeRestrictionFar
– Limita l'autofocus a profondità distanti. Utile nelle situazioni in cui gli oggetti noti come irrilevanti si trovano nel campo della visualizzazione (ad esempio, una cornice finestra).
Infine, è presente la SmoothAutoFocus
proprietà che rallenta l'algoritmo di attivazione automatica e lo esegue in incrementi più piccoli per evitare lo spostamento di artefatti durante la registrazione del video.
Nuovi controlli dello stato attivo in iOS 8
Oltre alle funzionalità già fornite da iOS 7 e versioni successive, le funzionalità seguenti sono ora disponibili per controllare lo stato attivo in iOS 8:
- Controllo manuale completo della posizione dell'obiettivo durante il blocco dello stato attivo.
- Osservazione chiave-valore della posizione dell'obiettivo in qualsiasi modalità messa a fuoco.
Per implementare le funzionalità precedenti, la AVCaptureDevice
classe è stata modificata per includere una proprietà di sola LensPosition
lettura usata per ottenere la posizione corrente dell'obiettivo della fotocamera.
Per controllare manualmente la posizione dell'obiettivo, il dispositivo di acquisizione deve essere in modalità messa a fuoco bloccata. Esempio:
CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;
Il SetFocusModeLocked
metodo del dispositivo di acquisizione viene usato per regolare la posizione dell'obiettivo della fotocamera. È possibile fornire una routine di callback facoltativa per ricevere una notifica quando la modifica diventa effettiva. Esempio:
ThisApp.CaptureDevice.LockForConfiguration(out Error);
ThisApp.CaptureDevice.SetFocusModeLocked(Position.Value,null);
ThisApp.CaptureDevice.UnlockForConfiguration();
Come illustrato nel codice precedente, il dispositivo di acquisizione deve essere bloccato per la configurazione prima che sia possibile apportare una modifica in Posizione lente. I valori validi per La posizione dell'obiettivo sono compresi tra 0,0 e 1,0.
Esempio di messa a fuoco manuale
Con il codice di installazione generale dell'acquisizione AV sul posto, un UIViewController
può essere aggiunto allo Storyboard dell'applicazione e configurato come segue:
La vista contiene gli elementi principali seguenti:
- Oggetto
UIImageView
che visualizzerà il feed video. - Oggetto
UISegmentedControl
che cambierà la modalità messa a fuoco da Automatico a Bloccato. - Oggetto
UISlider
che mostrerà e aggiornerà la posizione corrente dell'obiettivo.
Eseguire le operazioni seguenti per collegare il controller di visualizzazione per il controllo dello stato attivo manuale:
Aggiungere le istruzioni using seguenti:
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;
Aggiungere le variabili private seguenti:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
Aggiungere le proprietà calcolate seguenti:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Eseguire l'override del
ViewDidLoad
metodo e aggiungere il codice seguente: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(); }; }
Eseguire l'override del
ViewDidAppear
metodo e aggiungere quanto segue per avviare la registrazione al caricamento della visualizzazione: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 fotocamera in modalità Auto, il dispositivo di scorrimento si muove automaticamente quando la fotocamera regola lo stato attivo:
Toccare il segmento Bloccato e trascinare il dispositivo di scorrimento della posizione per regolare manualmente la posizione dell'obiettivo:
Arrestare l'applicazione.
Il codice precedente ha mostrato come monitorare la posizione dell'obiettivo quando la fotocamera è in modalità automatica o usare un dispositivo di scorrimento per controllare la posizione dell'obiettivo quando è in modalità bloccato.
Esposizione manuale
L'esposizione si riferisce alla luminosità di un'immagine rispetto alla luminosità della sorgente ed è determinata dalla quantità di luce che colpisce il sensore, per quanto tempo e dal livello di guadagno del sensore (mapping ISO). Fornendo un controllo manuale sull'esposizione, un'applicazione può fornire maggiore libertà all'utente finale e consentire loro di ottenere un aspetto stilizzato.
Usando i controlli di esposizione manuale, l'utente può acquisire un'immagine da non realisticamente brillante a scura e moody:
Anche in questo caso, questa operazione può essere eseguita automaticamente usando il controllo programmatico per le applicazioni scientifiche o tramite controlli manuali forniti dall'interfaccia utente delle applicazioni. In entrambi i casi, le nuove API di esposizione di iOS 8 offrono un controllo granulare sulle impostazioni di esposizione della fotocamera.
Funzionamento dell'esposizione
Prima di discutere i dettagli del controllo dell'esposizione in un'applicazione IOS 8. Di seguito viene illustrato il funzionamento dell'esposizione:
I tre elementi di base che interagiscono per controllare l'esposizione sono:
- Velocità otturatore: periodo di tempo in cui l'otturatore è aperto per consentire la luce sul sensore della fotocamera. Più breve è il tempo di apertura dell'otturatore, minore è la luce e l'immagine più nitida è (minore sfocatura del movimento). Più l'otturatore è aperto, maggiore è la luce è lasciato in e più sfocatura del movimento che si verifica.
- ISO Mapping – Questo è un termine preso in prestito dalla fotografia cinematografica e si riferisce alla sensibilità delle sostanze chimiche nel film alla luce. I valori ISO bassi nel film hanno una riproduzione del colore meno granulare e più fine; valori ISO bassi nei sensori digitali hanno meno rumore del sensore, ma meno luminosità. Maggiore è il valore ISO, più luminoso è l'immagine, ma con più rumore del sensore. "ISO" su un sensore digitale è una misura di guadagno elettronico, non una caratteristica fisica.
- Aperture lente : questa è la dimensione dell'apertura dell'obiettivo. In tutti i dispositivi iOS l'apertura dell'obiettivo è fissa, quindi gli unici due valori che possono essere usati per regolare l'esposizione sono Velocità otturatore e ISO.
Funzionamento dell'esposizione automatica continua
Prima di apprendere il funzionamento dell'esposizione manuale, è consigliabile comprendere il funzionamento dell'esposizione automatica continua in un dispositivo iOS.
Primo è il blocco di esposizione automatica, ha il compito di calcolare l'esposizione ideale ed è costantemente alimentato statistiche di misurazione. Usa queste informazioni per calcolare la combinazione ottimale di ISO e Velocità otturatore per ottenere la scena ben illuminata. Questo ciclo viene definito ciclo AE.
Funzionamento dell'esposizione bloccata
Si esaminerà ora il funzionamento dell'esposizione bloccata nei dispositivi iOS.
Anche in questo caso, si dispone del blocco di esposizione automatica che sta tentando di calcolare i valori ottimali di iOS e Durata. In questa modalità, tuttavia, il blocco AE viene disconnesso dal motore statistiche di misurazione.
Controlli di esposizione esistenti
iOS 7 e versioni successive forniscono i controlli Esposizione esistenti seguenti tramite la ExposureMode
proprietà :
AVCaptureExposureModeLocked
: campiona la scena una sola volta e usa tali valori in tutta la scena.AVCaptureExposureModeContinuousAutoExposure
– Campiona la scena continuamente per assicurarsi che sia ben illuminata.
Può ExposurePointOfInterest
essere usato per toccare per esporre la scena selezionando un oggetto di destinazione da esporre e l'applicazione può monitorare la proprietà per vedere quando viene modificata l'esposizione AdjustingExposure
.
Nuovi controlli di esposizione in iOS 8
Oltre alle funzionalità già fornite da iOS 7 e versioni successive, sono ora disponibili le funzionalità seguenti per controllare l'esposizione in iOS 8:
- Esposizione personalizzata completamente manuale.
- Ottenere, impostare e chiave-valore osservare IOS e Velocità otturatore (durata).
Per implementare le funzionalità precedenti, è stata aggiunta una nuova AVCaptureExposureModeCustom
modalità. Quando la fotocamera in è la modalità personalizzata, è possibile usare il codice seguente per regolare la durata dell'esposizione e l'ISO:
CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.LockExposure(DurationValue,ISOValue,null);
CaptureDevice.UnlockForConfiguration();
Nelle modalità Auto e Locked l'applicazione può modificare la distorsione della routine di esposizione automatica usando il codice seguente:
CaptureDevice.LockForConfiguration(out Error);
CaptureDevice.SetExposureTargetBias(Value,null);
CaptureDevice.UnlockForConfiguration();
Gli intervalli di impostazioni minimo e massimo dipendono dal dispositivo su cui è in esecuzione l'applicazione, quindi non devono mai essere hardcoded. Usare invece le proprietà seguenti per ottenere gli intervalli di valori minimo e massimo:
CaptureDevice.MinExposureTargetBias
CaptureDevice.MaxExposureTargetBias
CaptureDevice.ActiveFormat.MinISO
CaptureDevice.ActiveFormat.MaxISO
CaptureDevice.ActiveFormat.MinExposureDuration
CaptureDevice.ActiveFormat.MaxExposureDuration
Come illustrato nel codice precedente, il dispositivo di acquisizione deve essere bloccato per la configurazione prima di apportare una modifica dell'esposizione.
Esempio di esposizione manuale
Con il codice di installazione generale dell'acquisizione AV sul posto, un UIViewController
può essere aggiunto allo Storyboard dell'applicazione e configurato come segue:
La vista contiene gli elementi principali seguenti:
- Oggetto
UIImageView
che visualizzerà il feed video. - Oggetto
UISegmentedControl
che cambierà la modalità messa a fuoco da Automatico a Bloccato. - Quattro
UISlider
controlli che visualizzeranno e aggiorneranno Offset, Duration, ISO e Bias.
Eseguire le operazioni seguenti per collegare il controller di visualizzazione per il controllo dell'esposizione manuale:
Aggiungere le istruzioni using seguenti:
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;
Aggiungere le variabili private seguenti:
#region Private Variables private NSError Error; private bool Automatic = true; private nfloat ExposureDurationPower = 5; private nfloat ExposureMinimumDuration = 1.0f/1000.0f; #endregion
Aggiungere le proprietà calcolate seguenti:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Eseguire l'override del
ViewDidLoad
metodo e aggiungere il codice seguente: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(); }; }
Eseguire l'override del
ViewDidAppear
metodo e aggiungere quanto segue per avviare la registrazione al caricamento della visualizzazione: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 fotocamera in modalità Automatica, i dispositivi di scorrimento si muoveranno automaticamente man mano che la fotocamera regola l'esposizione:
Toccare il segmento Bloccato e trascinare il dispositivo di scorrimento Bias per regolare manualmente la distorsione dell'esposizione automatica:
Toccare il segmento Personalizzato e trascinare i dispositivi di scorrimento Durata e ISO per controllare manualmente l'esposizione:
Arrestare l'applicazione.
Il codice precedente ha illustrato come monitorare le impostazioni di esposizione quando la fotocamera è in modalità automatica e come usare i dispositivi di scorrimento per controllare l'esposizione quando si trova nelle modalità Bloccata o Personalizzata.
Bilanciamento del bianco manuale
I controlli di bilanciamento del bianco consentono agli utenti di regolare il bilanciamento del colosr in un'immagine per renderli più realistici. Diverse fonti di luce hanno temperature di colore diverse e le impostazioni della fotocamera usate per acquisire un'immagine devono essere regolate per compensare queste differenze. Anche in questo caso, consentendo all'utente di controllare il bilanciamento del bianco può apportare modifiche professionali che le routine automatiche non sono in grado di ottenere effetti artistici.
Ad esempio, la luce del giorno ha una casta blu, mentre le luci incandescenti del failover hanno una tinta arancione più calda e gialla. (Confusamente, i colori "cool" hanno temperature di colore più elevate rispetto ai colori "caldi". Le temperature dei colori sono una misura fisica, non una misura percettiva.
La mente umana è molto buona per compensare le differenze nella temperatura del colore, ma questo è qualcosa che una fotocamera non può fare. La fotocamera funziona aumentando il colore sullo spettro opposto per regolare le differenze di colore.
La nuova API di esposizione di iOS 8 consente all'applicazione di assumere il controllo del processo e fornire un controllo granulare sulle impostazioni di bilanciamento del bianco della fotocamera.
Funzionamento del bilanciamento del bianco
Prima di discutere i dettagli del controllo del bilanciamento del bianco in un'applicazione IOS 8. Di seguito viene illustrato il funzionamento del bilanciamento del bianco:
Nello studio della percezione dei colori, lo spazio dei colori RGB CIE 1931 e lo spazio colore XYZ CIE 1931 sono i primi spazi di colore definiti matematicamente. Sono stati creati dalla Commissione internazionale per l'illuminazione (CIE) nel 1931.
Il grafico precedente mostra tutti i colori visibili all'occhio umano, dal blu profondo al verde brillante al rosso brillante. Qualsiasi punto del diagramma può essere tracciato con un valore X e Y, come illustrato nel grafico precedente.
Come visibile nel grafico, esistono valori X e Y che possono essere tracciati sul grafico che si trovano al di fuori dell'intervallo di visione umana e di conseguenza questi colori non possono essere riprodotti da una fotocamera.
La curva più piccola del grafico precedente è denominata Planckian Locus, che esprime la temperatura del colore (in gradi kelvin), con numeri più alti sul lato blu (più caldo) e numeri inferiori sul lato rosso (più freddo). Sono utili per situazioni di illuminazione tipiche.
In condizioni di illuminazione mista, le regolazioni di bilanciamento del bianco dovranno deviare dal Locus planckiano per apportare le modifiche necessarie. In queste situazioni, la regolazione dovrà essere spostata sul lato verde o rosso/magenta della scala CIE.
I dispositivi iOS compensano i cast di colori aumentando il guadagno di colore opposto. Ad esempio, se una scena ha troppo blu, il guadagno rosso verrà incrementato per compensare. Questi valori di guadagno vengono calibrati per dispositivi specifici in modo che siano dipendenti dal dispositivo.
Controlli di bilanciamento del bianco esistenti
iOS 7 e versioni successive hanno fornito i controlli white balance esistenti seguenti tramite WhiteBalanceMode
la proprietà :
AVCapture WhiteBalance ModeLocked
: campiona la scena una sola volta e usa questi valori in tutta la scena.AVCapture WhiteBalance ModeContinuousAutoExposure
– Campiona continuamente la scena per garantire che sia ben bilanciata.
E l'applicazione può monitorare la AdjustingWhiteBalance
proprietà per vedere quando viene modificata l'esposizione.
Nuovi controlli di bilanciamento del bianco in iOS 8
Oltre alle funzionalità già fornite da iOS 7 e versioni successive, sono ora disponibili le funzionalità seguenti per controllare Il bilanciamento del bianco in iOS 8:
- Controllo completamente manuale dei guadagni RGB del dispositivo.
- Ottenere, impostare e chiave-valore Osservare i guadagni RGB del dispositivo.
- Supporto per il bilanciamento del bianco con una scheda grigia.
- Routine di conversione da e verso spazi di colore indipendenti dal dispositivo.
Per implementare le funzionalità precedenti, la AVCaptureWhiteBalanceGain
struttura è stata aggiunta con i membri seguenti:
RedGain
GreenGain
BlueGain
Il guadagno massimo di bilanciamento del bianco è attualmente quattro (4) e può essere pronto dalla MaxWhiteBalanceGain
proprietà. Quindi l'intervallo legale va da uno (1) a MaxWhiteBalanceGain
(4) attualmente.
La DeviceWhiteBalanceGains
proprietà può essere utilizzata per osservare i valori correnti. Usa SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains
per regolare i guadagni di saldo quando la fotocamera è in modalità di bilanciamento del bianco bloccato.
Routine di conversione
Le routine di conversione sono state aggiunte a iOS 8 per facilitare la conversione da e verso spazi di colore indipendenti dal dispositivo. Per implementare le routine di conversione, la AVCaptureWhiteBalanceChromaticityValues
struttura è stata aggiunta con i membri seguenti:
X
- è un valore compreso tra 0 e 1.Y
- è un valore compreso tra 0 e 1.
È stata aggiunta anche una AVCaptureWhiteBalanceTemperatureAndTintValues
struttura con i membri seguenti:
Temperature
- è un valore a virgola mobile in gradi Kelvin.Tint
- è un offset dal verde o magenta da 0 a 150 con valori positivi verso la direzione verde e negativo verso il magenta.
Utilizzare i metodi e CaptureDevice.GetDeviceWhiteBalanceGains
per eseguire la CaptureDevice.GetTemperatureAndTintValues
conversione tra temperatura e tinta, cromaticità e RGB ottengono spazi di colore.
Nota
Le routine di conversione sono più accurate, più il valore da convertire è nel Locus planckiano.
Supporto per schede grigie
Apple usa il termine Gray World per fare riferimento al supporto della scheda grigia integrato in iOS 8. Consente all'utente di concentrarsi su una scheda grigia fisica che copre almeno il 50% del centro del fotogramma e usa tale elemento per regolare il bilanciamento del bianco. Lo scopo della scheda grigia è ottenere il bianco che appare neutro.
Questa operazione può essere implementata in un'applicazione richiedendo all'utente di posizionare una scheda grigia fisica davanti alla fotocamera, monitorando la GrayWorldDeviceWhiteBalanceGains
proprietà e attendendo che i valori si stabilisano.
L'applicazione blocca quindi i guadagni di White Balance per il SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains
metodo usando i valori della GrayWorldDeviceWhiteBalanceGains
proprietà per applicare le modifiche.
Il dispositivo di acquisizione deve essere bloccato per la configurazione prima che sia possibile apportare una modifica in White Balance.
Esempio di bilanciamento del bianco manuale
Con il codice di installazione generale dell'acquisizione AV sul posto, un UIViewController
può essere aggiunto allo Storyboard dell'applicazione e configurato come segue:
La vista contiene gli elementi principali seguenti:
- Oggetto
UIImageView
che visualizzerà il feed video. - Oggetto
UISegmentedControl
che cambierà la modalità messa a fuoco da Automatico a Bloccato. - Due
UISlider
controlli che mostreranno e aggiorneranno temperatura e tinta. - Oggetto
UIButton
utilizzato per campionare uno spazio Gray Card (Gray World) e impostare il bilanciamento del bianco usando tali valori.
Eseguire le operazioni seguenti per collegare il controller di visualizzazione per il controllo di bilanciamento del bianco manuale:
Aggiungere le istruzioni using seguenti:
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;
Aggiungere le variabili private seguenti:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
Aggiungere le proprietà calcolate seguenti:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } public Timer SampleTimer { get; set; } #endregion
Aggiungere il metodo privato seguente per impostare il nuovo bilanciamento del bianco Temperature e Tinta:
#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
Eseguire l'override del
ViewDidLoad
metodo e aggiungere il codice seguente: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 (); } }; }
Eseguire l'override del
ViewDidAppear
metodo e aggiungere quanto segue per avviare la registrazione al caricamento della visualizzazione: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 (); } }
Salvare le modifiche apportate al codice ed eseguire l'applicazione.
Con la fotocamera in modalità Automatica, i dispositivi di scorrimento si muoveranno automaticamente man mano che la fotocamera regola il bilanciamento del bianco:
Toccare il segmento Bloccato e trascinare i dispositivi di scorrimento Temp e Tint per regolare manualmente il bilanciamento del bianco:
Con il segmento Bloccato ancora selezionato, posizionare una scheda grigia fisica davanti alla fotocamera e toccare il pulsante Scheda grigia per regolare il bilanciamento del bianco su Gray World:
Arrestare l'applicazione.
Il codice precedente ha illustrato come monitorare le impostazioni di bilanciamento del bianco quando la fotocamera è in modalità automatica o usare i dispositivi di scorrimento per controllare il bilanciamento del bianco quando è in modalità bloccata.
Acquisizione tra parentesi quadre
L'acquisizione tra parentesi è basata sulle impostazioni dei controlli della fotocamera manuale presentati in precedenza e consente all'applicazione di acquisire un momento nel tempo, in diversi modi.
Semplicemente dichiarato, l'acquisizione tra parentesi quadre è un burst di immagini ancora scattate con un'ampia gamma di impostazioni, dall'immagine all'immagine.
Usando l'acquisizione tra parentesi quadre in iOS 8, un'applicazione può impostare una serie di controlli manuali della fotocamera, eseguire un singolo comando e fare in modo che la scena corrente restituisca una serie di immagini per ognuno dei set di impostazioni manuali.
Nozioni di base sulle acquisizioni tra parentesi quadre
Anche in questo caso, l'acquisizione tra parentesi quadre è un burst di immagini ancora scattate con diverse impostazioni, dall'immagine all'immagine. I tipi di acquisizione tra parentesi quadre disponibili sono:
- Parentesi di esposizione automatica: in cui tutte le immagini hanno una quantità di distorsione varia.
- Parentesi di esposizione manuale: in cui tutte le immagini hanno una velocità di otturatore (durata) e una quantità ISO varia.
- Parentesi burst semplice: una serie di immagini ancora scattate in rapida successione.
Nuovi controlli di acquisizione tra parentesi quadre in iOS 8
Tutti i comandi di acquisizione tra parentesi quadre vengono implementati nella AVCaptureStillImageOutput
classe . Usare il CaptureStillImageBracket
metodo per ottenere una serie di immagini con la matrice di impostazioni specificata.
Sono state implementate due nuove classi per gestire le impostazioni:
AVCaptureAutoExposureBracketedStillImageSettings
– Ha una proprietà,ExposureTargetBias
, usata per impostare la distorsione per una parentesi di esposizione automatica.AVCaptureManual
ExposureBracketedStillImageSettings
– Ha due proprietà,ExposureDuration
eISO
, usato per impostare la velocità dell'otturatore e ISO per una parentesi di esposizione manuale.
Controlli di acquisizione tra parentesi quadre Do e Don'ts
Operazioni consentite
Di seguito è riportato un elenco di operazioni da eseguire quando si usano i controlli di acquisizione tra parentesi quadre in iOS 8:
- Preparare l'app per la situazione di acquisizione peggiore dei casi chiamando il
PrepareToCaptureStillImageBracket
metodo . - Si supponga che i buffer di esempio provengano dallo stesso pool condiviso.
- Per rilasciare la memoria allocata da una chiamata di preparazione precedente, chiamare
PrepareToCaptureStillImageBracket
di nuovo e inviarla una matrice di un oggetto.
Cose da evitare
Di seguito è riportato un elenco di operazioni che non devono essere eseguite quando si usano i controlli di acquisizione tra parentesi quadre in iOS 8:
- Non combinare i tipi di impostazioni di acquisizione tra parentesi quadre in un'unica acquisizione.
- Non richiedere più di
MaxBracketedCaptureStillImageCount
immagini in un'unica acquisizione.
Dettagli acquisizione tra parentesi quadre
Quando si lavora con l'acquisizione con parentesi quadre in iOS 8, è necessario prendere in considerazione i dettagli seguenti:
- Le impostazioni tra parentesi quadre sostituiscono temporaneamente le
AVCaptureDevice
impostazioni. - Le impostazioni di stabilizzazione flash e ancora immagine vengono ignorate.
- Tutte le immagini devono usare lo stesso formato di output (jpeg, png e così via)
- L'anteprima video può eliminare fotogrammi.
- L'acquisizione tra parentesi quadre è supportata in tutti i dispositivi compatibili con iOS 8.
Tenendo presente queste informazioni, si esaminerà un esempio di uso dell'acquisizione tra parentesi quadre in iOS 8.
Esempio di acquisizione tra parentesi quadre
Con il codice di installazione generale dell'acquisizione AV sul posto, un UIViewController
può essere aggiunto allo Storyboard dell'applicazione e configurato come segue:
La vista contiene gli elementi principali seguenti:
- Oggetto
UIImageView
che visualizzerà il feed video. - Tre
UIImageViews
che visualizzeranno i risultati dell'acquisizione. - Oggetto
UIScrollView
per ospitare il feed video e le visualizzazioni dei risultati. - Oggetto
UIButton
usato per acquisire un'acquisizione con parentesi quadre con alcune impostazioni predefinite.
Eseguire le operazioni seguenti per collegare il controller di visualizzazione per l'acquisizione tra parentesi quadre:
Aggiungere le istruzioni using seguenti:
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;
Aggiungere le variabili private seguenti:
#region Private Variables private NSError Error; private List<UIImageView> Output = new List<UIImageView>(); private nint OutputIndex = 0; #endregion
Aggiungere le proprietà calcolate seguenti:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } #endregion
Aggiungere il metodo privato seguente per compilare le visualizzazioni dell'immagine di output necessarie:
#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
Eseguire l'override del
ViewDidLoad
metodo e aggiungere il codice seguente: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(); }); }; }
Eseguire l'override del
ViewDidAppear
metodo e aggiungere il codice seguente: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 (); } }
Salvare le modifiche apportate al codice ed eseguire l'applicazione.
Incorniciare una scena e toccare il pulsante Acquisisci parentesi quadre:
Scorri verso destra verso sinistra per visualizzare le tre immagini scattate dall'acquisizione tra parentesi quadre:
Arrestare l'applicazione.
Il codice precedente ha illustrato come configurare e acquisire un'acquisizione con parentesi di esposizione automatica in iOS 8.
Riepilogo
In questo articolo è stata illustrata un'introduzione ai nuovi controlli della fotocamera manuale forniti da iOS 8 e sono state illustrate le nozioni di base di ciò che fanno e come funzionano. Sono stati forniti esempi di messa a fuoco manuale, esposizione manuale e bilanciamento del bianco manuale. Infine, abbiamo dato un esempio di acquisizione con parentesi quadre usando i controlli della fotocamera manuale descritti in precedenza