Manuelle Kamerasteuerelemente in Xamarin.iOS

Die manuellen Kamerasteuerelemente, die AVFoundation Framework von in iOS 8 bereitgestellt werden, ermöglichen es einer mobilen Anwendung, die vollständige Kontrolle über die Kamera eines iOS-Geräts zu übernehmen. Diese differenzierte Steuerungsebene kann verwendet werden, um professionelle Kameraanwendungen zu erstellen und Künstlerkompositionen bereitzustellen, indem die Parameter der Kamera optimiert werden, während sie ein Standbild oder Video aufnehmen.

Diese Kontrollen können auch bei der Entwicklung wissenschaftlicher oder industrieller Anwendungen nützlich sein, bei denen die Ergebnisse weniger auf die Richtigkeit oder Schönheit des Bildes ausgerichtet sind und eher auf die Hervorhebung einiger Merkmale oder Elemente des aufgenommenen Bilds ausgerichtet sind.

AVFoundation Capture-Objekte

Unabhängig davon, ob Video- oder Standbilder mit der Kamera auf einem iOS-Gerät aufgenommen werden, ist der Prozess, mit dem diese Bilder aufgenommen werden, weitgehend identisch. Dies gilt für Anwendungen, die die standardmäßigen automatisierten Kamerasteuerungen verwenden, oder für Anwendungen, die die neuen manuellen Kamerasteuerelemente nutzen:

Übersicht über AVFoundation Capture Objects

Die Eingabe wird von in AVCaptureDeviceInput eine AVCaptureSession über AVCaptureConnectioneine übernommen. Das Ergebnis wird entweder als Standbild oder als Videostream ausgegeben. Der gesamte Prozess wird durch eine AVCaptureDevicegesteuert.

Manuelle Steuerelemente bereitgestellt

Mithilfe der neuen APIs, die von iOS 8 bereitgestellt werden, kann die Anwendung die Kontrolle über die folgenden Kamerafeatures übernehmen:

  • Manueller Fokus : Indem der Endbenutzer die Kontrolle über den Fokus direkt übernehmen kann, kann eine Anwendung mehr Kontrolle über das aufgenommene Bild bieten.
  • Manuelle Belichtung : Durch die manuelle Steuerung der Belichtung kann eine Anwendung benutzern mehr Freiheit bieten und ihnen ermöglichen, ein stilisiertes Aussehen zu erzielen.
  • Manueller Weißabgleich – Weißabgleich wird verwendet, um die Farbe in einem Bild anzupassen– oft, um es realistisch aussehen zu lassen. Verschiedene Lichtquellen weisen unterschiedliche Farbtemperaturen auf, und die Kameraeinstellungen für die Aufnahme eines Bilds werden angepasst, um diese Unterschiede auszugleichen. Auch hier können Benutzer Anpassungen vornehmen, die nicht automatisch vorgenommen werden können, indem sie dem Benutzer die Kontrolle über den Weißabgleich gewähren.

iOS 8 bietet Erweiterungen und Erweiterungen für vorhandene iOS-APIs, um diese differenzierte Steuerung des Bildaufnahmeprozesses zu ermöglichen.

Requirements (Anforderungen)

Die folgenden Schritte sind erforderlich, um die in diesem Artikel beschriebenen Schritte auszuführen:

  • Xcode 7 und höher und iOS 8 oder höher : Die Xcode 7- und iOS 8- oder neueren APIs von Apple müssen auf dem Computer des Entwicklers installiert und konfiguriert werden.
  • Visual Studio für Mac: Die neueste Version von Visual Studio für Mac sollte auf dem Benutzergerät installiert und konfiguriert werden.
  • iOS 8-Gerät : Ein iOS-Gerät, auf dem die neueste Version von iOS 8 ausgeführt wird. Kamerafeatures können nicht im iOS-Simulator getestet werden.

Allgemeine Av Capture-Einrichtung

Beim Aufzeichnen von Videos auf einem iOS-Gerät ist immer ein allgemeiner Setupcode erforderlich. In diesem Abschnitt wird die minimale Einrichtung behandelt, die zum Aufzeichnen von Videos von der Kamera des iOS-Geräts und zum Anzeigen dieses Videos in Echtzeit in einem UIImageViewerforderlich ist.

Ausgabebeispielpufferdelegat

Eines der ersten Erforderlichen ist ein Delegat, um den Beispielausgabepuffer zu überwachen und ein Bild anzuzeigen, das aus dem Puffer in die UIImageView Benutzeroberfläche der Anwendung gegriffen wird.

Die folgende Routine überwacht den Beispielpuffer und aktualisiert die Benutzeroberfläche:

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
    }
}

Wenn diese Routine eingerichtet ist, kann geändert AppDelegate werden, um eine AV Capture-Sitzung zum Aufzeichnen eines Livevideofeeds zu öffnen.

Erstellen einer AV Capture-Sitzung

Die AV Capture-Sitzung wird verwendet, um die Aufzeichnung von Livevideos von der Kamera des iOS-Geräts zu steuern und ist erforderlich, um Videos in eine iOS-Anwendung zu übertragen. Da die Beispielanwendung ManualCameraControl die Erfassungssitzung an verschiedenen Stellen verwendet, wird sie in konfiguriert AppDelegate und für die gesamte Anwendung zur Verfügung gestellt.

Gehen Sie wie folgt vor, um die der Anwendung AppDelegate zu ändern und den erforderlichen Code hinzuzufügen:

  1. Doppelklicken Sie im Projektmappen-Explorer auf die AppDelegate.cs Datei, um sie zur Bearbeitung zu öffnen.

  2. Fügen Sie die folgenden "using"-Anweisungen am Anfang der Datei ein:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    
  3. Fügen Sie der -Klasse die folgenden privaten Variablen und berechneten Eigenschaften hinzu AppDelegate :

    #region Private Variables
    private NSError Error;
    #endregion
    
    #region Computed Properties
    public override UIWindow Window {get;set;}
    public bool CameraAvailable { get; set; }
    public AVCaptureSession Session { get; set; }
    public AVCaptureDevice CaptureDevice { get; set; }
    public OutputRecorder Recorder { get; set; }
    public DispatchQueue Queue { get; set; }
    public AVCaptureDeviceInput Input { get; set; }
    #endregion
    
  4. Überschreiben Sie die fertige Methode, und ändern Sie sie 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;
    }
    
  5. Speichern Sie die Änderungen in der Datei.

Mit diesem Code können die manuellen Kamerasteuerungen problemlos für Experimente und Tests implementiert werden.

Manueller Fokus

Indem der Endbenutzer den Fokus direkt steuern kann, kann eine Anwendung eine künstlerischere Kontrolle über das aufgenommene Bild bieten.

Beispielsweise kann ein professioneller Fotograf den Fokus eines Bilds weicher machen, um einen Bokeh-Effekt zu erzielen. Oder erstellen Sie einen Fokuspulleffekt.

Für Wissenschaftler oder Redakteure medizinischer Anwendungen kann die Anwendung die Linse für Experimente programmgesteuert bewegen. So oder so ermöglicht die neue API dem Endbenutzer oder der Anwendung, die Kontrolle über den Fokus zu übernehmen, wenn das Bild aufgenommen wird.

Funktionsweise des Fokus

Bevor Sie die Details zur Steuerung des Fokus in einer IOS 8-Anwendung besprechen. Sehen wir uns kurz an, wie der Fokus auf einem iOS-Gerät funktioniert:

Funktionsweise des Fokus auf einem iOS-Gerät

Licht tritt auf dem iOS-Gerät in die Kameralinse ein und wird auf einen Bildsensor fokussiert. Der Abstand der Linse vom Sensor steuert, wo der Fokuspunkt (der Bereich, in dem das Bild am schärfsten erscheint) im Verhältnis zum Sensor ist. Je weiter die Linse vom Sensor entfernt ist, die Entfernungsobjekte wirken am schärfsten und desto näher, objekte in der Nähe erscheinen am schärfsten.

Bei einem iOS-Gerät wird die Linse durch Magnete und Federn näher an den Sensor oder weiter entfernt. Daher ist eine exakte Positionierung der Linse unmöglich, da sie von Gerät zu Gerät variiert und von Parametern wie der Ausrichtung des Geräts oder dem Alter des Geräts und der Feder beeinflusst werden kann.

Wichtige Fokusbegriffe

Wenn es um den Fokus geht, gibt es einige Begriffe, mit denen der Entwickler vertraut sein sollte:

  • Schärfentiefe : Der Abstand zwischen dem nächstgelegenen und dem am weitesten fokussierten Objekt.
  • Makro : Dies ist das nahe Ende des Fokusspektrums und der nächste Abstand, in dem das Objektiv fokussiert werden kann.
  • Unendlich – Dies ist das ende des Fokusspektrums und ist die weiteste Entfernung, auf die das Objektiv fokussieren kann.
  • Hyperfokaler Abstand : Dies ist der Punkt im Fokusspektrum, an dem sich das am weitesten entfernte Objekt im Frame nur am ende des Fokus befindet. Anders ausgedrückt: Dies ist die Fokusposition, die die Schärfentiefe maximiert.
  • Objektivposition : Dies ist es, was alle oben genannten Begriffe steuert. Dies ist der Abstand der Linse vom Sensor und damit der Fokusregler.

Mit diesen Begriffen und Kenntnissen im Hinterkopf können die neuen Manuellen Fokussteuerungen erfolgreich in einer iOS 8-Anwendung implementiert werden.

Vorhandene Fokussteuerelemente

iOS 7 und frühere Versionen haben vorhandene Fokussteuerelemente über die FocusMode-Eigenschaft bereitgestellt:

  • AVCaptureFocusModeLocked – Der Fokus wird an einem einzelnen Fokuspunkt gesperrt.
  • AVCaptureFocusModeAutoFocus – Die Kamera fegt das Objektiv durch alle Brennpunkte, bis es einen scharfen Fokus findet, und bleibt dann dort.
  • AVCaptureFocusModeContinuousAutoFocus – Die Kamera wird immer dann neu fokussiert, wenn sie eine Nicht-Fokus-Bedingung erkennt.

Die vorhandenen Steuerelemente stellten auch einen festlegbaren Point of Interest über dieFocusPointOfInterest -Eigenschaft bereit, sodass der Benutzer tippen kann, um sich auf einen bestimmten Bereich zu konzentrieren. Die Anwendung kann auch die Linsenbewegung nachverfolgen, indem sie die IsAdjustingFocus -Eigenschaft überwacht.

Darüber hinaus wurde die Bereichseinschränkung von der AutoFocusRangeRestriction -Eigenschaft wie folgt bereitgestellt:

  • AVCaptureAutoFocusRangeRestrictionNear – Schränkt den Autofokus auf nahe gelegene Tiefen ein. Nützlich in Situationen wie dem Scannen eines QR-Codes oder Barcodes.
  • AVCaptureAutoFocusRangeRestrictionFar – Schränkt den Autofokus auf entfernte Tiefen ein. Nützlich in Situationen, in denen bekanntermaßen irrelevante Objekte im Sichtfeld befinden (für instance ein Fensterrahmen).

Schließlich gibt es die SmoothAutoFocus -Eigenschaft, die den Autofokusalgorithmus verlangsamt und in kleineren Schritten ausführt, um das Verschieben von Artefakten beim Aufzeichnen von Videos zu vermeiden.

Neue Fokussteuerelemente in iOS 8

Zusätzlich zu den Features, die bereits von iOS 7 und höher bereitgestellt werden, stehen jetzt die folgenden Features zur Steuerung des Fokus in iOS 8 zur Verfügung:

  • Vollständige manuelle Kontrolle der Objektivposition beim Sperren des Fokus.
  • Schlüssel-Wert-Beobachtung der Objektivposition in einem beliebigen Fokusmodus.

Um die oben genannten Features zu implementieren, wurde die AVCaptureDevice -Klasse so geändert, dass sie eine schreibgeschützte LensPosition Eigenschaft enthält, die zum Abrufen der aktuellen Position des Kameraobjektivs verwendet wird.

Um die Objektivposition manuell steuern zu können, muss sich das Aufnahmegerät im Gesperrten Fokusmodus befinden. Beispiel:

CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;

Die SetFocusModeLocked Methode des Aufnahmegeräts wird verwendet, um die Position des Kameraobjektivs anzupassen. Eine optionale Rückrufroutine kann bereitgestellt werden, um eine Benachrichtigung zu erhalten, wenn die Änderung wirksam wird. Beispiel:

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

Wie im obigen Code zu sehen, muss das Aufnahmegerät für die Konfiguration gesperrt werden, bevor eine Änderung der Objektivposition vorgenommen werden kann. Gültige Werte für die Objektivposition liegen zwischen 0,0 und 1,0.

Beispiel für manuellen Fokus

Wenn der Allgemeine AV Capture-Setupcode vorhanden ist, kann dem Storyboard der Anwendung hinzugefügt UIViewController und wie folgt konfiguriert werden:

Ein UIViewController kann den Anwendungen storyboard hinzugefügt und konfiguriert werden, wie hier für das Beispiel für den manuellen Fokus gezeigt.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView , der den Videofeed anzeigt.
  • Ein UISegmentedControl , der den Fokusmodus von Automatisch in Gesperrt ändert.
  • Ein UISlider , mit dem die aktuelle Objektivposition angezeigt und aktualisiert wird.

Führen Sie die folgenden Schritte aus, um den Ansichtscontroller für die manuelle Fokussteuerung zu verknüpfen:

  1. Fügen Sie die folgenden using-Anweisungen hinzu:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Fügen Sie die folgenden privaten Variablen hinzu:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Fügen Sie die folgenden berechneten Eigenschaften hinzu:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Überschreiben Sie die ViewDidLoad -Methode, und fügen Sie den folgenden Code hinzu:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Create a timer to monitor and update the UI
        SampleTimer = new Timer (5000);
        SampleTimer.Elapsed += (sender, e) => {
            // Update position slider
            Position.BeginInvokeOnMainThread(() =>{
                Position.Value = ThisApp.Input.Device.LensPosition;
            });
        };
    
        // Watch for value changes
        Segments.ValueChanged += (object sender, EventArgs e) => {
    
            // Lock device for change
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
    
            // Take action based on the segment selected
            switch(Segments.SelectedSegment) {
            case 0:
                // Activate auto focus and start monitoring position
                Position.Enabled = false;
                ThisApp.CaptureDevice.FocusMode = AVCaptureFocusMode.ContinuousAutoFocus;
                SampleTimer.Start();
                Automatic = true;
                break;
            case 1:
                // Stop auto focus and allow the user to control the camera
                SampleTimer.Stop();
                ThisApp.CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;
                Automatic = false;
                Position.Enabled = true;
                break;
            }
    
            // Unlock device
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        // Monitor position changes
        Position.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic) return;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.SetFocusModeLocked(Position.Value,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    }
    
  5. Überschreiben Sie die ViewDidAppear -Methode, und fügen Sie Folgendes hinzu, um die Aufzeichnung zu starten, wenn die Ansicht geladen wird:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
            SampleTimer.Start ();
        }
    }
    
  6. Wenn sich die Kamera im Auto-Modus befindet, bewegt sich der Schieberegler automatisch, wenn die Kamera den Fokus anpasst:

    Der Schieberegler wird automatisch bewegt, wenn die Kamera den Fokus in dieser Beispiel-App anpasst.

  7. Tippen Sie auf das Segment Gesperrt, und ziehen Sie den Positionsschieberegler, um die Objektivposition manuell anzupassen:

    Manuelles Anpassen der Objektivposition

  8. Beenden Sie die Anwendung.

Der obige Code hat gezeigt, wie die Objektivposition überwacht wird, wenn sich die Kamera im Automatischen Modus befindet, oder wie Sie die Objektivposition mithilfe eines Schiebereglers steuern, wenn sie sich im gesperrten Modus befindet.

Manuelle Belichtung

Die Belichtung bezieht sich auf die Helligkeit eines Bilds im Verhältnis zur Quellhelligkeit und wird durch die Höhe des Lichts, die Dauer und die Verstärkungsstufe des Sensors (ISO-Zuordnung) bestimmt. Durch die manuelle Kontrolle über die Belichtung kann eine Anwendung dem Endbenutzer mehr Freiheit bieten und es ihnen ermöglichen, ein stilisiertes Aussehen zu erzielen.

Mit den Manuellen Belichtungssteuerelementen kann der Benutzer ein Bild von unrealistisch hell bis dunkel und stimmungsstark machen:

Ein Beispiel für ein Bild, das die Belichtung von unrealistisch hell bis dunkel und stimmungsstark zeigt

Auch dies kann automatisch mithilfe der programmgesteuerten Steuerung für wissenschaftliche Anwendungen oder über manuelle Steuerungen erfolgen, die über die Benutzeroberfläche der Anwendungen bereitgestellt werden. In beiden Richtungen bieten die neuen iOS 8-Belichtungs-APIs eine differenzierte Steuerung der Belichtungseinstellungen der Kamera.

Funktionsweise der Belichtung

Bevor Sie die Details zur Steuerung der Belichtung in einer IOS 8-Anwendung besprechen. Sehen wir uns kurz an, wie die Belichtung funktioniert:

Funktionsweise der Belichtung

Die drei grundlegenden Elemente, die zusammenkommen, um die Belichtung zu steuern, sind:

  • Verschlusszeit : Dies ist die Dauer, in der der Verschluss geöffnet ist, um Licht auf den Kamerasensor zu lassen. Je kürzer die Öffnungszeit des Verschlusses ist, desto weniger Licht wird eingelassen und desto schärfer ist das Bild (weniger Bewegungsunschärfe). Je länger der Verschluss geöffnet ist, desto mehr Licht wird eingelassen und desto mehr Bewegungsunschärfe tritt auf.
  • ISO Mapping – Dieser Begriff ist aus der Filmfotografie entlehnt und bezieht sich auf die Empfindlichkeit der Chemikalien im Film gegenüber Licht. Niedrige ISO-Werte im Film haben weniger Körnung und feinere Farbwiedergabe; niedrige ISO-Werte auf digitalen Sensoren haben weniger Sensorgeräusche, aber weniger Helligkeit. Je höher der ISO-Wert, desto heller das Bild, aber mit mehr Sensorrauschen. "ISO" auf einem digitalen Sensor ist ein Maß für den elektronischen Gewinn, kein physisches Merkmal.
  • Lens Aperture – Dies ist die Größe der Objektivöffnung. Auf allen iOS-Geräten ist die Objektivblende fest, sodass die einzigen zwei Werte, die zum Anpassen der Belichtung verwendet werden können, Verschlusszeit und ISO sind.

Funktionsweise der kontinuierlichen automatischen Belichtung

Bevor Sie erfahren, wie die manuelle Belichtung funktioniert, sollten Sie verstehen, wie die kontinuierliche automatische Belichtung auf einem iOS-Gerät funktioniert.

Funktionsweise der kontinuierlichen automatischen Belichtung auf einem iOS-Gerät

Erstens ist der Automatische Belichtungsblock, er hat die Aufgabe, die ideale Belichtung zu berechnen, und wird kontinuierlich mit Verbrauchsstatistiken versorgt. Anhand dieser Informationen wird die optimale Mischung aus ISO und Verschlusszeit berechnet, um die Szene gut beleuchtet zu bekommen. Dieser Zyklus wird als AE-Schleife bezeichnet.

Funktionsweise der gesperrten Belichtung

Als Nächstes sehen wir uns an, wie die gesperrte Belichtung auf iOS-Geräten funktioniert.

Funktionsweise der gesperrten Belichtung auf iOS-Geräten

Auch hier haben Sie den Auto Exposure-Block, der versucht, die optimalen iOS- und Dauerwerte zu berechnen. In diesem Modus ist der AE-Block jedoch von der Verbrauchsstatistik-Engine getrennt.

Vorhandene Belichtungssteuerelemente

iOS 7 und höher stellen die folgenden vorhandenen Belichtungssteuerelemente über die -Eigenschaft bereit ExposureMode :

  • AVCaptureExposureModeLocked – Stichproben der Szene einmal und verwenden diese Werte in der gesamten Szene.
  • AVCaptureExposureModeContinuousAutoExposure – Stichproben der Szene kontinuierlich, um sicherzustellen, dass sie gut beleuchtet ist.

Kann ExposurePointOfInterest verwendet werden, um zu tippen, um die Szene verfügbar zu machen, indem ein Zielobjekt ausgewählt wird, für das verfügbar gemacht werden soll, und die Anwendung kann die AdjustingExposure -Eigenschaft überwachen, um zu sehen, wann die Belichtung angepasst wird.

Neue Belichtungssteuerelemente in iOS 8

Zusätzlich zu den Features, die bereits von iOS 7 und höher bereitgestellt wurden, stehen jetzt die folgenden Features zur Verfügung, um die Belichtung in iOS 8 zu steuern:

  • Vollständig manuelle benutzerdefinierte Belichtung.
  • Abrufen, Festlegen und Key-Value IoS und Verschlusszeit (Dauer) beobachten.

Um die oben genannten Features zu implementieren, wurde ein neuer AVCaptureExposureModeCustom Modus hinzugefügt. Wenn sich die Kamera im benutzerdefinierten Modus befindet, kann der folgende Code verwendet werden, um die Belichtungsdauer und ISO anzupassen:

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

In den Modi Auto und Gesperrt kann die Anwendung den Bias der automatischen Belichtungsroutine mithilfe des folgenden Codes anpassen:

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

Die minimalen und maximalen Einstellungsbereiche hängen vom Gerät ab, auf dem die Anwendung ausgeführt wird, sodass sie niemals hartcodiert werden sollten. Verwenden Sie stattdessen die folgenden Eigenschaften, um den minimalen und maximalen Wertbereich abzurufen:

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

Wie im obigen Code zu sehen, muss das Aufnahmegerät für die Konfiguration gesperrt werden, bevor eine Änderung der Belichtung vorgenommen werden kann.

Beispiel für manuelle Belichtung

Wenn der Allgemeine AV Capture-Setupcode vorhanden ist, kann dem Storyboard der Anwendung hinzugefügt UIViewController und wie folgt konfiguriert werden:

Ein UIViewController kann den Anwendungen Storyboard hinzugefügt und konfiguriert werden, wie hier für das Beispiel für die manuelle Belichtung gezeigt.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView , der den Videofeed anzeigt.
  • Ein UISegmentedControl , der den Fokusmodus von Automatisch in Gesperrt ändert.
  • Vier UISlider Steuerelemente, die Offset, Duration, ISO und Bias anzeigen und aktualisieren.

Führen Sie die folgenden Schritte aus, um den Ansichtscontroller für die manuelle Belichtungssteuerung zu verkabeln:

  1. Fügen Sie die folgenden using-Anweisungen hinzu:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Fügen Sie die folgenden privaten Variablen hinzu:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    private nfloat ExposureDurationPower = 5;
    private nfloat ExposureMinimumDuration = 1.0f/1000.0f;
    #endregion
    
  3. Fügen Sie die folgenden berechneten Eigenschaften hinzu:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Überschreiben Sie die ViewDidLoad -Methode, und fügen Sie den folgenden Code hinzu:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Set min and max values
        Offset.MinValue = ThisApp.CaptureDevice.MinExposureTargetBias;
        Offset.MaxValue = ThisApp.CaptureDevice.MaxExposureTargetBias;
    
        Duration.MinValue = 0.0f;
        Duration.MaxValue = 1.0f;
    
        ISO.MinValue = ThisApp.CaptureDevice.ActiveFormat.MinISO;
        ISO.MaxValue = ThisApp.CaptureDevice.ActiveFormat.MaxISO;
    
        Bias.MinValue = ThisApp.CaptureDevice.MinExposureTargetBias;
        Bias.MaxValue = ThisApp.CaptureDevice.MaxExposureTargetBias;
    
        // Create a timer to monitor and update the UI
        SampleTimer = new Timer (5000);
        SampleTimer.Elapsed += (sender, e) => {
            // Update position slider
            Offset.BeginInvokeOnMainThread(() =>{
                Offset.Value = ThisApp.Input.Device.ExposureTargetOffset;
            });
    
            Duration.BeginInvokeOnMainThread(() =>{
                var newDurationSeconds = CMTimeGetSeconds(ThisApp.Input.Device.ExposureDuration);
                var minDurationSeconds = Math.Max(CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MinExposureDuration), ExposureMinimumDuration);
                var maxDurationSeconds = CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MaxExposureDuration);
                var p = (newDurationSeconds - minDurationSeconds) / (maxDurationSeconds - minDurationSeconds);
                Duration.Value = (float)Math.Pow(p, 1.0f/ExposureDurationPower);
            });
    
            ISO.BeginInvokeOnMainThread(() => {
                ISO.Value = ThisApp.Input.Device.ISO;
            });
    
            Bias.BeginInvokeOnMainThread(() => {
                Bias.Value = ThisApp.Input.Device.ExposureTargetBias;
            });
        };
    
        // Watch for value changes
        Segments.ValueChanged += (object sender, EventArgs e) => {
    
            // Lock device for change
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
    
            // Take action based on the segment selected
            switch(Segments.SelectedSegment) {
            case 0:
                // Activate auto exposure and start monitoring position
                Duration.Enabled = false;
                ISO.Enabled = false;
                ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure;
                SampleTimer.Start();
                Automatic = true;
                break;
            case 1:
                // Lock exposure and allow the user to control the camera
                SampleTimer.Stop();
                ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.Locked;
                Automatic = false;
                Duration.Enabled = false;
                ISO.Enabled = false;
                break;
            case 2:
                // Custom exposure and allow the user to control the camera
                SampleTimer.Stop();
                ThisApp.CaptureDevice.ExposureMode = AVCaptureExposureMode.Custom;
                Automatic = false;
                Duration.Enabled = true;
                ISO.Enabled = true;
                break;
            }
    
            // Unlock device
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        // Monitor position changes
        Duration.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic) return;
    
            // Calculate value
            var p = Math.Pow(Duration.Value,ExposureDurationPower);
            var minDurationSeconds = Math.Max(CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MinExposureDuration),ExposureMinimumDuration);
            var maxDurationSeconds = CMTimeGetSeconds(ThisApp.CaptureDevice.ActiveFormat.MaxExposureDuration);
            var newDurationSeconds = p * (maxDurationSeconds - minDurationSeconds) +minDurationSeconds;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.LockExposure(CMTime.FromSeconds(p,1000*1000*1000),ThisApp.CaptureDevice.ISO,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        ISO.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic) return;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.LockExposure(ThisApp.CaptureDevice.ExposureDuration,ISO.Value,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    
        Bias.ValueChanged += (object sender, EventArgs e) => {
    
            // If we are in the automatic mode, ignore changes
            // if (Automatic) return;
    
            // Update Focus position
            ThisApp.CaptureDevice.LockForConfiguration(out Error);
            ThisApp.CaptureDevice.SetExposureTargetBias(Bias.Value,null);
            ThisApp.CaptureDevice.UnlockForConfiguration();
        };
    }
    
  5. Überschreiben Sie die ViewDidAppear -Methode, und fügen Sie Folgendes hinzu, um die Aufzeichnung zu starten, wenn die Ansicht geladen wird:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
            SampleTimer.Start ();
        }
    }
    
  6. Wenn sich die Kamera im Auto-Modus befindet, bewegen sich die Schieberegler automatisch, wenn die Kamera die Belichtung anpasst:

    Die Schieberegler werden automatisch bewegt, wenn die Kamera die Belichtung anpasst.

  7. Tippen Sie auf das Gesperrte Segment, und ziehen Sie den Schieberegler Bias, um die Verzerrung der automatischen Belichtung manuell anzupassen:

    Manuelles Anpassen der Verzerrung der automatischen Belichtung

  8. Tippen Sie auf das Benutzerdefinierte Segment, und ziehen Sie die Schieberegler Dauer und ISO, um die Belichtung manuell zu steuern:

    Ziehen Sie die Schieberegler Dauer und ISO, um die Belichtung manuell zu steuern.

  9. Beenden Sie die Anwendung.

Der obige Code hat gezeigt, wie die Belichtungseinstellungen überwacht werden, wenn sich die Kamera im automatischen Modus befindet, und wie Schieberegler verwendet werden, um die Belichtung zu steuern, wenn sie sich im Gesperrten oder benutzerdefinierten Modus befindet.

Manueller Weißabgleich

Mit Weißabgleichssteuerelementen können Benutzer das Gleichgewicht des Kolosses in einem Bild anpassen, damit sie realistischer aussehen. Verschiedene Lichtquellen weisen unterschiedliche Farbtemperaturen auf, und die Kameraeinstellungen für die Aufnahme eines Bilds müssen angepasst werden, um diese Unterschiede auszugleichen. Auch hier, indem sie dem Benutzer die Kontrolle über den Weißabgleich erlauben, können sie professionelle Anpassungen vornehmen, die die automatischen Routinen nicht in der Lage sind, künstlerische Effekte zu erzielen.

Beispielbild mit Anpassungen des manuellen Weißabgleichs

Für instance hat das Tageslicht einen blaulichen Abguss, während Wolframglühlampen einen wärmeren, gelb-orangen Farbton haben. (Verwirrenderweise haben "kalte" Farben höhere Farbtemperaturen als "warme" Farben. Farbtemperaturen sind ein physisches Maß, kein wahrnehmungsbezogenes Maß.)

Der menschliche Geist ist sehr gut darin, die Unterschiede in der Farbtemperatur auszugleichen, aber das ist etwas, was eine Kamera nicht kann. Die Kamera arbeitet, indem sie die Farbe im gegenüberliegenden Spektrum erhöht, um die Farbunterschiede anzupassen.

Die neue iOS 8-Belichtungs-API ermöglicht es der Anwendung, die Kontrolle über den Prozess zu übernehmen und eine differenzierte Kontrolle über die Weißabgleichseinstellungen der Kamera bereitzustellen.

Funktionsweise des Weißabgleichs

Bevor Sie die Details zur Steuerung des Weißabgleichs in einer IOS 8-Anwendung besprechen. Sehen wir uns kurz an, wie der Weißabgleich funktioniert:

In der Untersuchung der Farbwahrnehmung sind der CIE 1931 RGB-Farbraum und der CIE 1931 XYZ-Farbraum die ersten mathematisch definierten Farbräume. Sie wurden 1931 von der International Commission on Illumination (CIE) ins Leben gerufen.

Der CIE 1931 RGB-Farbraum und der CIE 1931 XYZ-Farbraum

Das obige Diagramm zeigt uns alle Farben, die für das menschliche Auge sichtbar sind, von tiefem Blau über helles Grün bis hin zu leuchtendem Rot. Jeder Punkt im Diagramm kann mit einem X- und Y-Wert dargestellt werden, wie im obigen Diagramm dargestellt.

Wie im Diagramm sichtbar, gibt es X- und Y-Werte, die auf dem Graphen gezeichnet werden können, der außerhalb des Bereichs des menschlichen Sehens liegen würde, und daher können diese Farben nicht von einer Kamera reproduziert werden.

Die kleinere Kurve im obigen Diagramm wird als Plancksche Locus bezeichnet, der die Farbtemperatur (in Grad Kelvin) mit höheren Zahlen auf der blauen Seite (heißer) und niedrigeren Zahlen auf der roten Seite (Kühler) ausdrückt. Diese sind für typische Beleuchtungssituationen nützlich.

Bei gemischten Lichtverhältnissen müssen die Weißabgleichsanpassungen vom Planckschen Locus abweichen, um die erforderlichen Änderungen vorzunehmen. In diesen Situationen muss die Anpassung entweder auf die grüne oder rote/magenta-Seite der CIE-Skala verschoben werden.

iOS-Geräte kompensieren Farbumwandlungen, indem sie die entgegengesetzte Farbzunahme verstärken. Wenn instance eine Szene zu viel Blau aufweist, wird der rote Gewinn erhöht, um den Ausgleich zu erzielen. Diese Verstärkungswerte werden für bestimmte Geräte kalibriert, sodass sie geräteabhängig sind.

Vorhandene Weißabgleichssteuerelemente

iOS 7 und höher stellt die folgenden vorhandenen Weißabgleichssteuerelemente über WhiteBalanceMode die -Eigenschaft bereit:

  • AVCapture WhiteBalance ModeLocked – Beispiele für die Szene einmal und verwenden diese Werte in der gesamten Szene.
  • AVCapture WhiteBalance ModeContinuousAutoExposure – Stichproben der Szene kontinuierlich, um sicherzustellen, dass sie gut ausbalanciert ist.

Außerdem kann die Anwendung die AdjustingWhiteBalance Eigenschaft überwachen, um zu sehen, wann die Belichtung angepasst wird.

Neue Weißabgleichssteuerelemente in iOS 8

Zusätzlich zu den Features, die bereits von iOS 7 und höher bereitgestellt werden, stehen jetzt die folgenden Features zur Steuerung des Weißabgleichs in iOS 8 zur Verfügung:

  • Vollständig manuelle Steuerung der RGB-Zuwächse des Geräts.
  • Abrufen, Festlegen und Key-Value Beobachten sie die RGB-Gewinne des Geräts.
  • Unterstützung für Weißabgleich mit einer grauen Karte.
  • Konvertierungsroutinen in und aus geräteunabhängigen Farbräumen.

Um die oben genannten Features zu implementieren, wurde die AVCaptureWhiteBalanceGain -Struktur mit den folgenden Membern hinzugefügt:

  • RedGain
  • GreenGain
  • BlueGain

Der maximale Weißabgleichsgewinn beträgt derzeit vier (4) und kann über die MaxWhiteBalanceGain -Eigenschaft bereit sein. Der rechtliche Bereich liegt also derzeit zwischen 1 (1) und MaxWhiteBalanceGain (4).

Die DeviceWhiteBalanceGains -Eigenschaft kann verwendet werden, um die aktuellen Werte zu beobachten. Verwenden Sie SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains , um die Gleichgewichtsgewinne anzupassen, wenn sich die Kamera im gesperrten Weißabgleichmodus befindet.

Konvertierungsroutinen

Konvertierungsroutinen wurden zu iOS 8 hinzugefügt, um die Konvertierung in und aus geräteunabhängigen Farbräumen zu unterstützen. Um die Konvertierungsroutinen zu implementieren, wurde die AVCaptureWhiteBalanceChromaticityValues -Struktur mit den folgenden Membern hinzugefügt:

  • X - ist ein Wert von 0 bis 1.
  • Y - ist ein Wert von 0 bis 1.

Außerdem AVCaptureWhiteBalanceTemperatureAndTintValues wurde eine -Struktur mit den folgenden Membern hinzugefügt:

  • Temperature – ist ein Gleitkommawert in Grad Kelvin.
  • Tint - ist ein Offset von Grün oder Magenta von 0 bis 150 mit positiven Werten zur grünen Richtung und negativ in der Magenta.

Verwenden Sie die CaptureDevice.GetTemperatureAndTintValues-Methode und die CaptureDevice.GetDeviceWhiteBalanceGains-Methode, um zwischen Temperatur und Tönung, Chromität und RGB-Farbraum zu konvertieren.

Hinweis

Die Konvertierungsroutinen sind genauer, je näher der zu konvertierende Wert an den Planckschen Locus liegt.

Unterstützung für graue Karten

Apple verwendet den Begriff Gray World, um sich auf die in iOS 8 integrierte Gray Card-Unterstützung zu beziehen. Es ermöglicht dem Benutzer, sich auf eine physische Graue Karte zu konzentrieren, die mindestens 50 % der Mitte des Rahmens abdeckt, und verwendet diese, um den Weißabgleich anzupassen. Der Zweck der grauen Karte besteht darin, weiß zu erreichen, das neutral erscheint.

Dies kann in einer Anwendung implementiert werden, indem der Benutzer aufgefordert wird, einen physischen grauen Karte vor der Kamera zu platzieren, die GrayWorldDeviceWhiteBalanceGains Eigenschaft zu überwachen und zu warten, bis sich die Werte absetzen.

Die Anwendung würde dann die Weißabgleichsgewinne für die SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains -Methode mit den Werten der GrayWorldDeviceWhiteBalanceGains -Eigenschaft sperren, um die Änderungen anzuwenden.

Das Erfassungsgerät muss für die Konfiguration gesperrt werden, bevor eine Änderung des Weißabgleichs vorgenommen werden kann.

Beispiel für manuellen Weißabgleich

Wenn der Allgemeine AV Capture-Setupcode vorhanden ist, kann dem Storyboard der Anwendung hinzugefügt UIViewController und wie folgt konfiguriert werden:

Ein UIViewController kann den Anwendungen storyboard hinzugefügt und konfiguriert werden, wie hier für das beispiel für den manuellen Weißabgleich gezeigt.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView , der den Videofeed anzeigt.
  • Ein UISegmentedControl , der den Fokusmodus von Automatisch in Gesperrt ändert.
  • Zwei UISlider Steuerelemente, die Temperatur und Tönung anzeigen und aktualisieren.
  • Ein UIButton , der verwendet wird, um ein Leerzeichen für die graue Karte (Graue Welt) abzutasten und den Weißabgleich mithilfe dieser Werte festzulegen.

Führen Sie die folgenden Schritte aus, um den Ansichtscontroller für die manuelle Weißabgleichsteuerung zu verkabeln:

  1. Fügen Sie die folgenden using-Anweisungen hinzu:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Fügen Sie die folgenden privaten Variablen hinzu:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Fügen Sie die folgenden berechneten Eigenschaften hinzu:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Fügen Sie die folgende private Methode hinzu, um den neuen Weißabgleich Temperatur und Farbton festzulegen:

    #region Private Methods
    void SetTemperatureAndTint() {
        // Grab current temp and tint
        var TempAndTint = new AVCaptureWhiteBalanceTemperatureAndTintValues (Temperature.Value, Tint.Value);
    
        // Convert Color space
        var gains = ThisApp.CaptureDevice.GetDeviceWhiteBalanceGains (TempAndTint);
    
        // Set the new values
        if (ThisApp.CaptureDevice.LockForConfiguration (out Error)) {
            gains = NomralizeGains (gains);
            ThisApp.CaptureDevice.SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains (gains, null);
            ThisApp.CaptureDevice.UnlockForConfiguration ();
        }
    }
    
    AVCaptureWhiteBalanceGains NomralizeGains (AVCaptureWhiteBalanceGains gains)
    {
        gains.RedGain = Math.Max (1, gains.RedGain);
        gains.BlueGain = Math.Max (1, gains.BlueGain);
        gains.GreenGain = Math.Max (1, gains.GreenGain);
    
        float maxGain = ThisApp.CaptureDevice.MaxWhiteBalanceGain;
        gains.RedGain = Math.Min (maxGain, gains.RedGain);
        gains.BlueGain = Math.Min (maxGain, gains.BlueGain);
        gains.GreenGain = Math.Min (maxGain, gains.GreenGain);
    
        return gains;
    }
    #endregion
    
  5. Überschreiben Sie die ViewDidLoad -Methode, und fügen Sie den folgenden Code hinzu:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        // Hide no camera label
        NoCamera.Hidden = ThisApp.CameraAvailable;
    
        // Attach to camera view
        ThisApp.Recorder.DisplayView = CameraView;
    
        // Set min and max values
        Temperature.MinValue = 1000f;
        Temperature.MaxValue = 10000f;
    
        Tint.MinValue = -150f;
        Tint.MaxValue = 150f;
    
        // Create a timer to monitor and update the UI
        SampleTimer = new Timer (5000);
        SampleTimer.Elapsed += (sender, e) => {
            // Convert color space
            var TempAndTint = ThisApp.CaptureDevice.GetTemperatureAndTintValues (ThisApp.CaptureDevice.DeviceWhiteBalanceGains);
    
            // Update slider positions
            Temperature.BeginInvokeOnMainThread (() => {
                Temperature.Value = TempAndTint.Temperature;
            });
    
            Tint.BeginInvokeOnMainThread (() => {
                Tint.Value = TempAndTint.Tint;
            });
        };
    
        // Watch for value changes
        Segments.ValueChanged += (sender, e) => {
            // Lock device for change
            if (ThisApp.CaptureDevice.LockForConfiguration (out Error)) {
    
                // Take action based on the segment selected
                switch (Segments.SelectedSegment) {
                case 0:
                // Activate auto focus and start monitoring position
                    Temperature.Enabled = false;
                    Tint.Enabled = false;
                    ThisApp.CaptureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance;
                    SampleTimer.Start ();
                    Automatic = true;
                    break;
                case 1:
                // Stop auto focus and allow the user to control the camera
                    SampleTimer.Stop ();
                    ThisApp.CaptureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.Locked;
                    Automatic = false;
                    Temperature.Enabled = true;
                    Tint.Enabled = true;
                    break;
                }
    
                // Unlock device
                ThisApp.CaptureDevice.UnlockForConfiguration ();
            }
        };
    
        // Monitor position changes
        Temperature.TouchUpInside += (sender, e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic)
                return;
    
            // Update white balance
            SetTemperatureAndTint ();
        };
    
        Tint.TouchUpInside += (sender, e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic)
                return;
    
            // Update white balance
            SetTemperatureAndTint ();
        };
    
        GrayCardButton.TouchUpInside += (sender, e) => {
    
            // If we are in the automatic mode, ignore changes
            if (Automatic)
                return;
    
            // Get gray card values
            var gains = ThisApp.CaptureDevice.GrayWorldDeviceWhiteBalanceGains;
    
            // Set the new values
            if (ThisApp.CaptureDevice.LockForConfiguration (out Error)) {
                ThisApp.CaptureDevice.SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains (gains, null);
                ThisApp.CaptureDevice.UnlockForConfiguration ();
            }
        };
    }
    
  6. Überschreiben Sie die ViewDidAppear -Methode, und fügen Sie Folgendes hinzu, um die Aufzeichnung zu starten, wenn die Ansicht geladen wird:

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
            SampleTimer.Start ();
        }
    }
    
  7. Speichern Sie die Änderungen im Code, und führen Sie die Anwendung aus.

  8. Wenn sich die Kamera im Auto-Modus befindet, bewegen sich die Schieberegler automatisch, wenn die Kamera den Weißabgleich anpasst:

    Die Schieberegler werden automatisch bewegt, wenn die Kamera den Weißabgleich anpasst.

  9. Tippen Sie auf das Segment Gesperrt, und ziehen Sie die Schieberegler Temp und Tint, um den Weißabgleich manuell anzupassen:

    Ziehen Sie die Schieberegler Temp und Tint, um den Weißabgleich manuell anzupassen.

  10. Wenn das Segment Gesperrt noch ausgewählt ist, platzieren Sie einen physischen grauen Karte vor der Kamera, und tippen Sie auf die Schaltfläche Graue Karte, um den Weißabgleich an die Graue Welt anzupassen:

    Tippen Sie auf die Schaltfläche Graue Karte, um den Weißabgleich an die Graue Welt anzupassen.

  11. Beenden Sie die Anwendung.

Der obige Code hat gezeigt, wie die Weißabgleichseinstellungen überwacht werden, wenn sich die Kamera im automatischen Modus befindet, oder wie Sie den Weißabgleich im gesperrten Modus mithilfe von Schiebereglern steuern.

Erfassung in Klammern

Die Aufnahme in Klammern basiert auf den Einstellungen der oben dargestellten manuellen Kamerasteuerungen und ermöglicht der Anwendung, einen Moment auf verschiedene Arten zu erfassen.

Einfach gesagt, ist bracketed Capture ein Burst von Standbildern, die mit einer Vielzahl von Einstellungen von Bild zu Bild aufgenommen wurden.

Funktionsweise der Erfassung in Klammern

Mit der Aufnahme in Klammern in iOS 8 kann eine Anwendung eine Reihe von manuellen Kamerasteuerungen voreinstellen, einen einzelnen Befehl ausgeben und die aktuelle Szene eine Reihe von Bildern für jede der manuellen Voreinstellungen zurückgeben lassen.

Grundlagen zur Erfassung in Klammern

Auch hier ist Bracketed Capture ein Burst von Standbildern, die mit unterschiedlichen Einstellungen von Bild zu Bild aufgenommen wurden. Die verfügbaren Typen von "Bracketed Capture" sind:

  • Automatische Belichtungsklammer – bei der alle Bilder einen unterschiedlichen Bias-Wert aufweisen.
  • Manuelle Belichtungsklammer – bei der alle Bilder eine unterschiedliche Verschlusszeit (Dauer) und ISO-Menge aufweisen.
  • Einfache Burstklammer – Eine Reihe von Standbildern, die in schneller Folge aufgenommen wurden.

Neue Erfassungssteuerelemente in Klammern in iOS 8

Alle Capture-Befehle in Klammern werden in der AVCaptureStillImageOutput -Klasse implementiert. Verwenden Sie die CaptureStillImageBracket-Methode, um eine Reihe von Bildern mit dem angegebenen Array von Einstellungen abzurufen.

Zwei neue Klassen wurden implementiert, um Einstellungen zu verarbeiten:

  • AVCaptureAutoExposureBracketedStillImageSettings – Es verfügt über eine Eigenschaft, ExposureTargetBias, die verwendet wird, um die Verzerrung für eine automatische Belichtungsklammer festzulegen.
  • AVCaptureManualExposureBracketedStillImageSettings – Es verfügt über zwei Eigenschaften, ExposureDuration und ISO, die verwendet werden, um die Verschlusszeit und ISO für eine manuelle Belichtungsklammer festzulegen.

Do's und Don'ts für klammerte Erfassungssteuerelemente

Empfohlene Vorgehensweisen

Im Folgenden finden Sie eine Liste der Dinge, die bei verwendung der Steuerelemente für die Erfassung in Klammern in iOS 8 ausgeführt werden sollten:

  • Bereiten Sie die App auf die Notfallaufnahme vor, indem Sie die PrepareToCaptureStillImageBracket -Methode aufrufen.
  • Angenommen, die Beispielpuffer stammen aus demselben freigegebenen Pool.
  • Um den Speicher freizugeben, der durch einen vorherigen Vorbereitungsaufruf zugewiesen wurde, rufen Sie erneut auf PrepareToCaptureStillImageBracket , und senden Sie ihm ein Array eines Objekts.

DONT‘s

Im Folgenden finden Sie eine Liste der Dinge, die nicht ausgeführt werden sollten, wenn Sie die In Klammern klammerten Capture-Steuerelemente in iOS 8 verwenden:

  • Mischen Sie keine Einstellungstypen mit Klammern für die Erfassung in einer einzelnen Erfassung.
  • Fordern Sie nicht mehr als MaxBracketedCaptureStillImageCount Bilder in einer einzelnen Aufnahme an.

Details zur Erfassung in Klammern

Die folgenden Details sollten bei der Arbeit mit bracketed Capture in iOS 8 berücksichtigt werden:

  • Klammern setzen die AVCaptureDevice Einstellungen vorübergehend außer Kraft.
  • Blitz- und Bildstabilisierungseinstellungen werden ignoriert.
  • Alle Bilder müssen das gleiche Ausgabeformat (JPEG, PNG usw.) verwenden.
  • Die Videovorschau kann Frames löschen.
  • Die Klammererfassung wird auf allen Geräten unterstützt, die mit iOS 8 kompatibel sind.

Unter Berücksichtigung dieser Informationen sehen wir uns ein Beispiel für die Verwendung von Bracketed Capture in iOS 8 an.

Beispiel für die Klammererfassung

Wenn der Allgemeine AV Capture-Setupcode vorhanden ist, kann dem Storyboard der Anwendung hinzugefügt UIViewController und wie folgt konfiguriert werden:

Ein UIViewController kann dem Storyboard der Anwendungen hinzugefügt und konfiguriert werden, wie im folgenden Beispiel für die Erfassung in Klammern gezeigt.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView , der den Videofeed anzeigt.
  • Drei UIImageViews , die die Ergebnisse der Erfassung anzeigen.
  • Ein UIScrollView , um den Videofeed und die Ergebnisansichten zu beherbergen.
  • Ein UIButton , der verwendet wird, um eine Klammererfassung mit einigen voreingestellten Einstellungen zu verwenden.

Führen Sie die folgenden Schritte aus, um den Ansichtscontroller für die Erfassung in Klammern zu verknüpfen:

  1. Fügen Sie die folgenden using-Anweisungen hinzu:

    using System;
    using System.Drawing;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using CoreImage;
    
  2. Fügen Sie die folgenden privaten Variablen hinzu:

    #region Private Variables
    private NSError Error;
    private List<UIImageView> Output = new List<UIImageView>();
    private nint OutputIndex = 0;
    #endregion
    
  3. Fügen Sie die folgenden berechneten Eigenschaften hinzu:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    #endregion
    
  4. Fügen Sie die folgende private Methode hinzu, um die erforderlichen Ausgabeimageansichten zu erstellen:

    #region Private Methods
    private UIImageView BuildOutputView(nint n) {
    
        // Create a new image view controller
        var imageView = new UIImageView (new CGRect (CameraView.Frame.Width * n, 0, CameraView.Frame.Width, CameraView.Frame.Height));
    
        // Load a temp image
        imageView.Image = UIImage.FromFile ("Default-568h@2x.png");
    
        // Add a label
        UILabel label = new UILabel (new CGRect (0, 20, CameraView.Frame.Width, 24));
        label.TextColor = UIColor.White;
        label.Text = string.Format ("Bracketed Image {0}", n);
        imageView.AddSubview (label);
    
        // Add to scrolling view
        ScrollView.AddSubview (imageView);
    
        // Return new image view
        return imageView;
    }
    #endregion
    
  5. Überschreiben Sie die ViewDidLoad -Methode, und fügen Sie den folgenden Code hinzu:

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

    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);
    
        // Start udating the display
        if (ThisApp.CameraAvailable) {
            // Remap to this camera view
            ThisApp.Recorder.DisplayView = CameraView;
    
            ThisApp.Session.StartRunning ();
        }
    }
    
    
  7. Speichern Sie die Änderungen im Code, und führen Sie die Anwendung aus.

  8. Rahmen Sie eine Szene ein, und tippen Sie auf die Schaltfläche Klammer erfassen:

    Rahmen einer Szene und Tippen auf die Schaltfläche

  9. Wischen Sie nach rechts nach links, um die drei Bilder anzuzeigen, die von der Klammeraufnahme aufgenommen wurden:

    Wischen Sie von rechts nach links, um die drei Bilder anzuzeigen, die von der Aufnahme in Klammern aufgenommen wurden

  10. Beenden Sie die Anwendung.

Der obige Code hat gezeigt, wie Sie eine automatische Erfassung in Klammern mit Belichtung in iOS 8 konfigurieren und verwenden.

Zusammenfassung

In diesem Artikel haben wir eine Einführung in die neuen manuellen Kamerasteuerungen von iOS 8 behandelt und die Grundlagen ihrer Aufgaben und ihrer Funktionsweise behandelt. Wir haben Beispiele für den manuellen Fokus, die manuelle Belichtung und den manuellen Weißabgleich gegeben. Schließlich haben wir ein Beispiel für eine Klammeraufnahme mit den zuvor beschriebenen manuellen Kamerasteuerelementen angegeben.