Freigeben über


Manuelle Kamera Steuerelemente in Xamarin.iOS

Die von iOS AVFoundation Framework 8 bereitgestellten manuellen Kamera Steuerelemente ermöglichen es einer mobilen Anwendung, die volle Kontrolle über die Kamera eines iOS-Geräts zu übernehmen. Diese fein abgestimmte Steuerungsebene kann verwendet werden, um professionelle Kameraanwendungen zu erstellen und Künstlerkompositionen bereitzustellen, indem sie die Parameter der Kamera beim Aufnehmen eines Bilds oder Videos optimieren.

Diese Steuerelemente 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 Bilds ausgerichtet sind und mehr darauf ausgerichtet sind, einige Features oder Elemente des aufgenommenen Bilds hervorzuheben.

AVFoundation Capture Objects

Ob Videoaufnahmen oder stille Bilder, die die Kamera auf einem iOS-Gerät verwenden, ist der Prozess, der zum Aufnehmen dieser Bilder verwendet wird, weitgehend identisch. Dies gilt für Anwendungen, die die standardmäßigen automatisierten Kamerasteuerelemente oder diejenigen verwenden, die die neuen manuellen Kamera-Steuerelemente nutzen:

Übersicht über AVFoundation Capture Objects

Eingaben werden von einer AVCaptureDeviceInput in eine AVCaptureSession durch eine AVCaptureConnection. Das Ergebnis wird entweder als Stillbild oder als Videostream ausgegeben. Der gesamte Prozess wird durch ein AVCaptureDevice.

Manuelle Steuerelemente bereitgestellt

Mit den 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 manuelle Kontrolle über die Belichtung kann eine Anwendung benutzern mehr Freiheit bieten und ihnen ein stilisiertes Aussehen ermöglichen.
  • Manuelles Weißabgleich – Weißabgleich wird verwendet, um die Farbe in einem Bild anzupassen – oft um es realistisch zu gestalten. Verschiedene Lichtquellen weisen unterschiedliche Farbtemperaturen auf, und die Kameraeinstellungen, die zum Aufnehmen eines Bilds verwendet werden, werden angepasst, um diese Unterschiede auszugleichen. Durch das Zulassen der Kontrolle über den Weißabgleich können Benutzer Anpassungen vornehmen, die nicht automatisch ausgeführt werden können.

iOS 8 bietet Erweiterungen und Verbesserungen an vorhandenen iOS-APIs, um diese fein abgestimmte Kontrolle über den Bildaufnahmeprozess bereitzustellen.

Anforderungen

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

  • Xcode 7+ und iOS 8 oder höher – Apples Xcode 7 und iOS 8 oder neuere APIs 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. Kamera Features können nicht im iOS-Simulator getestet werden.

Allgemeines Einrichten der AV-Erfassung

Beim Aufzeichnen von Videos auf einem iOS-Gerät gibt es einen allgemeinen Setupcode, der immer erforderlich ist. In diesem Abschnitt wird die minimale Einrichtung behandelt, die zum Aufzeichnen von Videos von der Kamera des iOS-Geräts erforderlich ist und dieses Video in Echtzeit in einem UIImageView.

Ausgabepufferdelegat

Einer der ersten Erforderlichen ist ein Delegat, um den Beispielausgabepuffer zu überwachen und ein Bild anzuzeigen, das vom Puffer in eine UIImageView in der Anwendungsbenutzeroberfläche 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
    }
}

Mit dieser Routine können Sie AppDelegate so geändert werden, dass eine AV-Aufnahmesitzung geöffnet wird, um einen Livevideofeed aufzuzeichnen.

Erstellen einer AV-Aufnahmesitzung

Die AV Capture-Sitzung wird verwendet, um die Aufzeichnung von Livevideos über die Kamera des iOS-Geräts zu steuern und ist erforderlich, um Video in eine iOS-Anwendung zu integrieren. Da die Beispielbeispielanwendung ManualCameraControl die Aufnahmesitzung an verschiedenen Stellen verwendet, wird sie in der AppDelegate gesamten Anwendung konfiguriert und zur Verfügung gestellt.

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

  1. Doppelklicken Sie auf die AppDelegate.cs Datei im Projektmappen-Explorer, 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 Kamera Steuerelemente einfach für Experimente und Tests implementiert werden.

Manueller Fokus

Indem der Endbenutzer die Steuerung des Fokus direkt übernehmen kann, kann eine Anwendung mehr künstlerische Kontrolle über das aufgenommene Bild bieten.

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

For scientists or a writer of medical applications, the application might want to move the lens around for experiments. Die neue API ermöglicht entweder dem Endbenutzer oder der Anwendung, den Fokus zu dem Zeitpunkt, zu dem das Bild aufgenommen wird, zu übernehmen.

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 wechselt in das Kameraobjektiv auf dem iOS-Gerät und konzentriert sich auf einen Bildsensor. Der Abstand der Linse vom Sensor steuert, wo der Fokuspunkt (der Bereich, in dem das Bild am schärfesten angezeigt wird) im Verhältnis zum Sensor liegt. Je weiter die Linse vom Sensor entfernt ist, scheinen Abstandsobjekte am schärfesten und die näheren, nahe objekte scheinen schärfer zu sein.

In einem iOS-Gerät wird die Linse näher an oder weiter vom Sensor durch Magnete und Federn bewegt. Daher ist eine genaue Positionierung der Linse unmöglich, da sie von Gerät zu Gerät variieren wird und von Parametern wie der Ausrichtung des Geräts oder dem Alter des Geräts und feder beeinflusst werden kann.

Wichtige Fokusbegriffe

Beim Umgang mit dem Fokus gibt es einige Begriffe, mit denen der Entwickler vertraut sein sollte:

  • Tiefe des Felds – Der Abstand zwischen den nächstgelegenen und den weitesten Fokusobjekten.
  • Makro – Dies ist das nahe Ende des Fokusspektrums und der nächstgelegene Abstand, in dem sich die Linse konzentrieren kann.
  • Infinity – Dies ist das weit entfernte Ende des Fokusspektrums und ist der weiteste Abstand, auf den sich die Linse konzentrieren kann.
  • Hyperfokalabstand – Dies ist der Punkt im Fokusspektrum, an dem sich das weiteste Objekt im Frame gerade am ende des Fokus befindet. Das heißt, dies ist die Fokusposition, die die Tiefe des Felds maximiert.
  • Objektivposition – Das steuert alle oben genannten Begriffe. Dies ist der Abstand der Linse vom Sensor und damit der Controller des Fokus.

Mit diesen Begriffen und Kenntnissen 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 FocusModedie Eigenschaft als:

  • AVCaptureFocusModeLocked – Der Fokus ist an einem einzelnen Fokuspunkt gesperrt.
  • AVCaptureFocusModeAutoFocus – Die Kamera reißt die Linse durch alle Brennpunkte, bis sie den scharfen Fokus findet und dann dort bleibt.
  • AVCaptureFocusModeContinuousAutoFocus – Die Kamera wird immer dann neu ausgerichtet, wenn sie eine Außer-Fokus-Bedingung erkennt.

Die vorhandenen Steuerelemente haben auch einen festgelegten interessanten Punkt über dieFocusPointOfInterest Eigenschaft bereitgestellt, sodass der Benutzer tippen kann, um sich auf einen bestimmten Bereich zu konzentrieren. Die Anwendung kann die Objektivbewegung auch 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 objekte, die als irrelevant bekannt sind, sich im Ansichtsfeld befinden (z. B. ein Fensterrahmen).

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

Neue Fokussteuerelemente in iOS 8

Zusätzlich zu den features, die bereits von iOS 7 und höher bereitgestellt wurden, stehen nun die folgenden Features zum Steuern des Fokus in iOS 8 zur Verfügung:

  • Vollständige manuelle Steuerung der Objektivposition beim Sperren des Fokus.
  • Key-Value-Beobachtung der Objektivposition in jedem 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 manuelle Steuerung der Objektivposition zu übernehmen, 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 Benachrichtigungen 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 gezeigt, muss das Aufnahmegerät für die Konfiguration gesperrt werden, bevor eine Änderung der Objektivposition vorgenommen werden kann. Gültige Objektivpositionswerte liegen zwischen 0,0 und 1,0.

Beispiel für manuellen Fokus

Wenn der Allgemeine AV-Aufnahmesetupcode eingerichtet ist, kann dem Storyboard der Anwendung ein UIViewController Code hinzugefügt und wie folgt konfiguriert werden:

Ein UIViewController kann dem Storyboard der Anwendungen hinzugefügt und wie hier gezeigt für das beispiel für den manuellen Fokus konfiguriert werden.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView Videofeed, das den Videofeed anzeigt.
  • Ein UISegmentedControl Steuerelement, das den Fokusmodus von "Automatisch" in "Gesperrt" ändert.
  • Ein UISlider Element, das die aktuelle Objektivposition anzeigt und aktualisiert.

Führen Sie die folgenden Schritte aus, um den Ansichtscontroller für die manuelle Fokussteuerung 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. Ü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 Automodus befindet, wird der Schieberegler automatisch verschoben, wenn die Kamera den Fokus anpasst:

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

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

    Manuelle Anpassung 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 einen Schieberegler verwenden, um die Objektivposition zu steuern, wenn sie sich im gesperrten Modus befindet.

Manuelle Belichtung

Die Belichtung bezieht sich auf die Helligkeit eines Bilds relativ zur Quellhelligkeit und wird bestimmt, wie viel Licht auf den Sensor trifft, wie lange und wie lange das Maß des Sensors (ISO-Zuordnung) ist. 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 stimmungsvoll aufnehmen:

Beispiel eines Bilds, das die Belichtung von unrealistisch hell bis dunkel und stimmungsvoll zeigt

Auch hier kann dies automatisch mithilfe der programmgesteuerten Steuerung für wissenschaftliche Anwendungen oder über manuelle Steuerelemente erfolgen, die von der Benutzeroberfläche der Anwendungen bereitgestellt werden. Auf beide Weise bieten die neuen iOS 8-Belichtungs-APIs eine differenzierte Kontrolle über die Belichtungseinstellungen der Kamera.

Funktionsweise der Belichtung

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

Funktionsweise der Belichtung

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

  • Verschlussgeschwindigkeit – Dies ist die Zeit, die der Verschluss geöffnet ist, um Licht auf den Kamerasensor zu lassen. Je kürzer die Zeit, in der der Verschluss geöffnet ist, desto weniger Licht wird eingeblennt, und das Bild wird schärfer (weniger Bewegungsunschärfe). Je länger der Verschluss geöffnet ist, desto mehr Licht wird ins Licht gelassen und desto mehr Bewegung weichzeichnen, das auftritt.
  • ISO Mapping – Dies ist ein Begriff aus Filmfotografie und bezieht sich auf die Empfindlichkeit der Chemikalien im Film auf Licht. Niedrige ISO-Werte im Film haben weniger Körnung und feinere Farbwiedergabe; Niedrige ISO-Werte für digitale Sensoren haben weniger Sensorgeräusche, aber weniger Helligkeit. Je höher der ISO-Wert, desto heller das Bild, aber mit mehr Sensorgeräuschen. "ISO" auf einem digitalen Sensor ist ein Maß für elektronischen Gewinn, kein physisches Merkmal.
  • Lens Blende – Dies ist die Größe der Objektivöffnung. Auf allen iOS-Geräten ist die Objektivblende fest, daher sind die einzigen beiden Werte, die zum Anpassen der Belichtung verwendet werden können, Verschlussgeschwindigkeit und ISO.

Funktionsweise der kontinuierlichen automatischen Belichtung

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

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

Erstens ist der Auto-Belichtungsblock, er hat die Aufgabe, die ideale Exposition zu berechnen und wird kontinuierlich metering Stats gefüttert. Es verwendet diese Informationen, um die optimale Mischung aus ISO und Verschlussgeschwindigkeit zu berechnen, um die Szene gut beleuchtet zu bekommen. Dieser Zyklus wird als AE-Schleife bezeichnet.

Funktionsweise der gesperrten Belichtung

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

Funktionsweise der gesperrten Belichtung auf iOS-Geräten

Auch hier haben Sie den automatischen Belichtungsblock, der versucht, die optimalen iOS- und Dauerwerte zu berechnen. In diesem Modus wird der AE-Block jedoch vom Metering Stats-Modul getrennt.

Vorhandene Belichtungssteuerelemente

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

  • AVCaptureExposureModeLocked – Zeigt die Szene einmal an und verwendet diese Werte in der gesamten Szene.
  • AVCaptureExposureModeContinuousAutoExposure – Proben Sie die Szene kontinuierlich, um sicherzustellen, dass sie gut beleuchtet ist.

Sie ExposurePointOfInterest können verwendet werden, um die Szene verfügbar zu machen, indem Sie ein Zielobjekt auswählen, das verfügbar gemacht werden soll, und die Anwendung kann die AdjustingExposure Eigenschaft überwachen, um festzustellen, 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 Steuerung der Belichtung in iOS 8 zur Verfügung:

  • Vollständig manuelle benutzerdefinierte Belichtung.
  • Abrufen, Festlegen und Schlüsselwert beobachten IOS und Verschlussgeschwindigkeit (Dauer).

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();

Im Modus "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 Mindest- und Maximaleinstellungsbereiche 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 die Minimal- und Maximalwertbereiche abzurufen:

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

Wie im obigen Code gezeigt, 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-Aufnahmesetupcode eingerichtet ist, kann dem Storyboard der Anwendung ein UIViewController Code hinzugefügt und wie folgt konfiguriert werden:

Ein UIViewController kann dem Storyboard der Anwendungen hinzugefügt und wie hier gezeigt für das beispiel für die manuelle Belichtung konfiguriert werden.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView Videofeed, das den Videofeed anzeigt.
  • Ein UISegmentedControl Steuerelement, das 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 Belichtungskontrolle 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 Automodus befindet, werden die Schieberegler automatisch verschoben, wenn die Kamera die Belichtung anpasst:

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

  7. Tippen Sie auf das Gesperrte Segment, und ziehen Sie den Bias-Schieberegler, 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

  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

Steuerelemente für den Weißabgleich ermöglichen Es Benutzern, das Gleichgewicht von Koloss in einem Bild anzupassen, damit sie realistischer aussehen. Verschiedene Lichtquellen weisen unterschiedliche Farbtemperaturen auf, und die Kameraeinstellungen, die zum Aufnehmen eines Bilds verwendet werden, müssen angepasst werden, um diese Unterschiede auszugleichen. Durch die Möglichkeit, den Weißabgleich zu kontrollieren, 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

Beispielsweise hat Tageslicht einen blaufarbenen Guss, während Tungsten-Glühlampen einen wärmeren, gelb-orangefarbenen Farbton aufweisen. (Verwirrenderweise haben "coole" Farben höhere Farbtemperaturen als "warme" Farben. Farbtemperaturen sind ein physisches Maß, kein wahrnehmbares Maß.)

Der menschliche Geist ist sehr gut, um die Unterschiede bei der Farbtemperatur auszugleichen, aber dies ist etwas, was eine Kamera nicht tun kann. Die Kamera funktioniert, indem die Farbe auf dem gegenüberliegenden Spektrum erhöht wird, um sich an die Farbunterschiede anzupassen.

Die neue iOS 8-Belichtungs-API ermöglicht es der Anwendung, die Kontrolle über den Prozess zu übernehmen und präzise Kontrolle über die Einstellungen des Weißabgleichs 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:

Bei 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 Internationalen Kommission für Beleuchtung (CIE) geschaffen.

CIE 1931 RGB-Farbraum und CIE 1931 XYZ-Farbraum

Das obige Diagramm zeigt uns alle Farben, die für das menschliche Auge sichtbar sind, von tiefblau bis hellgrün bis hellrot. Jeder Punkt auf dem Diagramm kann mit einem X- und Y-Wert gezeichnet werden, wie im diagramm oben dargestellt.

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

Die kleinere Kurve im obigen Diagramm wird als Planckian 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 nützlich für typische Beleuchtungssituationen.

Bei gemischten Lichtverhältnissen müssen die Anpassungen des Weißabgleichs von der Planckischen Locus abweichen, um die erforderlichen Änderungen vorzunehmen. In diesen Fällen muss die Anpassung entweder auf die grüne oder rote/Magenta-Seite der CIE-Skala verschoben werden.

iOS-Geräte entschädigen Farbumschläge, indem sie die entgegengesetzte Farbzunahme erhöhen. Wenn z. B. eine Szene zu viel Blau aufweist, wird der rote Gewinn erhöht, um dies zu kompensieren. Diese Verstärkungswerte werden für bestimmte Geräte kalibriert, sodass sie vom Gerät abhängig sind.

Vorhandene Steuerelemente für den Weißabgleich

iOS 7 und höher haben die folgenden vorhandenen White Balance-Steuerelemente über WhiteBalanceMode die Eigenschaft bereitgestellt:

  • AVCapture WhiteBalance ModeLocked – Zeigt die Szene einmal und verwendet diese Werte in der gesamten Szene.
  • AVCapture WhiteBalance ModeContinuousAutoExposure – Proben Sie die Szene kontinuierlich, um sicherzustellen, dass sie gut ausgeglichen ist.

Und die Anwendung kann die AdjustingWhiteBalance Eigenschaft überwachen, um festzustellen, wann die Belichtung angepasst wird.

Neue Steuerelemente für den Weißabgleich 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 den Weißabgleich in iOS 8 zu steuern:

  • Vollständige manuelle Steuerung des Geräts RGB-Gewinne.
  • Abrufen, Festlegen und Schlüsselwert Beobachten Sie die RGB-Gewinne des Geräts.
  • Unterstützung für den Weißabgleich mithilfe einer grauen Karte.
  • Konvertierungsroutinen in und von unabhängigen Farbräumen des Geräts.

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

  • RedGain
  • GreenGain
  • BlueGain

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

Die DeviceWhiteBalanceGains Eigenschaft kann verwendet werden, um die aktuellen Werte zu beobachten. Hier können SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains Sie die Balancegewinne anpassen, wenn sich die Kamera im gesperrten Weißabgleichmodus befindet.

Konvertierungsroutinen

Konvertierungsroutinen wurden iOS 8 hinzugefügt, um bei der Konvertierung in und von gerätenunabhängigen Farbräumen zu helfen. 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 wurde eine AVCaptureWhiteBalanceTemperatureAndTintValues Struktur mit den folgenden Mitgliedern 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 in Richtung grün und negativ in die Magenta.

Verwenden Sie die CaptureDevice.GetTemperatureAndTintValuesMethoden CaptureDevice.GetDeviceWhiteBalanceGains, um zwischen Temperatur und Farbton, Farbton und RGB-Farbräume zu konvertieren.

Hinweis

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

Unterstützung für graue Karten

Apple verwendet den Begriff Gray World, um auf die in iOS 8 integrierte Graukartenunterstützung zu verweisen. Der Benutzer kann sich auf eine physische graue Karte konzentrieren, die mindestens 50 % der Mitte des Frames abdeckt und dies verwendet, um den Weißabgleich anzupassen. Der Zweck der Graukarte besteht darin, weiß zu erreichen, das neutral erscheint.

Dies kann in einer Anwendung implementiert werden, indem der Benutzer aufgefordert wird, eine physische graue Karte vor der Kamera zu platzieren, die GrayWorldDeviceWhiteBalanceGains Eigenschaft zu überwachen und zu warten, bis sich die Werte niederlassen.

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

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

Beispiel für manuelles Weißabgleich

Wenn der Allgemeine AV-Aufnahmesetupcode eingerichtet ist, kann dem Storyboard der Anwendung ein UIViewController Code hinzugefügt und wie folgt konfiguriert werden:

Ein UIViewController kann dem Storyboard der Anwendungen hinzugefügt und wie hier für das Beispiel für den manuellen Weißabgleich konfiguriert werden.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView Videofeed, das den Videofeed anzeigt.
  • Ein UISegmentedControl Steuerelement, das den Fokusmodus von "Automatisch" in "Gesperrt" ändert.
  • Zwei UISlider Steuerelemente, die die Temperatur und den Farbton anzeigen und aktualisieren.
  • Ein UIButton Beispiel für ein Graukarten-Leerzeichen (Graue Welt) und zum Festlegen des Weißabgleichs mithilfe dieser Werte.

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 am Code, und führen Sie die Anwendung aus.

  8. Wenn sich die Kamera im Automodus befindet, werden die Schieberegler automatisch verschoben, wenn die Kamera den Weißabgleich anpasst:

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

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

    Ziehen Sie die Schieberegler

  10. Wenn das Gesperrte Segment weiterhin ausgewählt ist, platzieren Sie ein physisches graues Karte vor der Kamera, und tippen Sie auf die Schaltfläche "Graue Karte", um den Weißabgleich an die Grauwelt anzupassen:

    Tippen Sie auf die Schaltfläche

  11. Beenden Sie die Anwendung.

Der obige Code hat gezeigt, wie Sie die Einstellungen für den Weißabgleich überwachen, wenn sich die Kamera im automatischen Modus befindet, oder mithilfe von Schiebereglern den Weißabgleich steuern, wenn sie sich im gesperrten Modus befindet.

Klammernerfassung

Die Klammernerfassung basiert auf den Einstellungen aus den oben dargestellten manuellen Kamera-Steuerelementen und ermöglicht es der Anwendung, einen Moment in der Zeit auf unterschiedliche Weise zu erfassen.

Einfach gesagt, Klammern aufnahme ist ein Platz von stillen Bildern, die mit einer Vielzahl von Einstellungen von Bild zu Bild aufgenommen wurden.

Funktionsweise der Klammernerfassung

Mithilfe der Klammernerfassung in iOS 8 kann eine Anwendung eine Reihe von manuellen Kamera-Steuerelementen voreinstellen, einen einzelnen Befehl ausgeben und die aktuelle Szene eine Reihe von Bildern für jede der manuellen Voreinstellungen zurückgeben lassen.

Grundlagen der Klammererfassung

Auch hier ist "Bracketed Capture" ein Platz von stillen Bildern, die mit unterschiedlichen Einstellungen von Bild zu Bild aufgenommen wurden. Die verfügbaren Typen der Klammernerfassung sind:

  • Automatische Belichtungsklammer – wenn alle Bilder einen unterschiedlichen Bias-Wert aufweisen.
  • Manuelle Belichtungsklammer – wenn alle Bilder eine unterschiedliche Verschlussgeschwindigkeit (Dauer) und ISO-Menge aufweisen.
  • Simple Burst Bracket – Eine Reihe von stillen Bildern, die schnell hintereinander aufgenommen wurden.

Neue in Klammern klammerte Aufnahmesteuerelemente in iOS 8

Alle Klammernerfassungsbefehle werden in der AVCaptureStillImageOutput Klasse implementiert. Verwenden Sie die CaptureStillImageBracketMethode, um eine Reihe von Bildern mit dem angegebenen Array von Einstellungen abzurufen.

Für die Behandlung von Einstellungen wurden zwei neue Klassen implementiert:

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

Klammern von Aufnahmesteuerelementen dos und Don'ts

Empfohlene Vorgehensweisen

Im Folgenden finden Sie eine Liste der Dinge, die bei Verwendung der Klammernerfassungssteuerelemente in iOS 8 ausgeführt werden sollten:

  • Bereiten Sie die App auf die Fallaufnahmesituation vor, indem Sie die PrepareToCaptureStillImageBracket Methode aufrufen.
  • Gehen Sie davon aus, dass die Beispielpuffer aus demselben freigegebenen Pool stammen.
  • Um den Speicher freizugeben, der von einem vorherigen Vorbereitungsaufruf zugewiesen wurde, rufen Sie erneut auf PrepareToCaptureStillImageBracket , und senden Sie es an ein Array eines Objekts.

Was Sie nicht tun sollten

Im Folgenden finden Sie eine Liste der Dinge, die nicht ausgeführt werden sollten, wenn Sie die Steuerelemente für die Klammernerfassung in iOS 8 verwenden:

  • Mischen Sie die Einstellungstypen "Klammern" nicht in einer einzelnen Aufzeichnung.
  • Fordern Sie nicht mehr als MaxBracketedCaptureStillImageCount Bilder in einer einzigen Aufnahme an.

Klammern der Erfassungsdetails

Bei der Arbeit mit Klammern in iOS 8 sollten die folgenden Details berücksichtigt werden:

  • Klammern einstellungen setzen die AVCaptureDevice Einstellungen vorübergehend außer Kraft.
  • Blitz- und Stillbildstabilisierungseinstellungen werden ignoriert.
  • Alle Bilder müssen dasselbe Ausgabeformat (jpeg, png usw.) verwenden.
  • Die Videovorschau kann Frames ablegen.
  • Die Klammernerfassung wird auf allen Geräten unterstützt, die mit iOS 8 kompatibel sind.

Sehen wir uns mit diesen Informationen ein Beispiel für die Verwendung der Klammernerfassung in iOS 8 an.

Beispiel für Klammernerfassung

Wenn der Allgemeine AV-Aufnahmesetupcode eingerichtet ist, kann dem Storyboard der Anwendung ein UIViewController Code hinzugefügt und wie folgt konfiguriert werden:

Ein UIViewController kann dem Storyboard der Anwendungen hinzugefügt und konfiguriert werden, wie hier gezeigt.

Die Ansicht enthält die folgenden Standard Elemente:

  • Ein UIImageView Videofeed, das den Videofeed anzeigt.
  • Drei UIImageViews , die die Ergebnisse der Aufnahme anzeigen.
  • A UIScrollView to house the video feed and result views.
  • Eine UIButton verwendet, um eine Klammernerfassung mit einigen voreingestellten Einstellungen zu übernehmen.

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

  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 Ausgabebildansichten 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 am Code, und führen Sie die Anwendung aus.

  8. Frame a scene and tap the Capture Bracket button:

    Rahmen einer Szene und Tippen auf die Schaltfläche

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

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

  10. Beenden Sie die Anwendung.

Der obige Code hat gezeigt, wie Sie eine automatische Belichtungsklammernerfassung in iOS 8 konfigurieren und übernehmen.

Zusammenfassung

In diesem Artikel haben wir eine Einführung in die neuen manuellen Kamera Steuerelemente behandelt, die von iOS 8 bereitgestellt werden, und die Grundlagen ihrer Funktionsweise behandelt. Wir haben Beispiele für manuellen Fokus, manuelle Belichtung und manuelles Weißabgleich gegeben. Schließlich haben wir ein Beispiel für eine Klammernerfassung mit den zuvor erläuterten manuellen Kamera-Steuerelementen gegeben.