Udostępnij za pośrednictwem


Ręczne kontrolki Aparat w środowisku Xamarin.iOS

Kontrolki ręczne Aparat udostępniane przez AVFoundation Framework program w systemie iOS 8 umożliwiają aplikacji mobilnej przejęcie pełnej kontroli nad aparatem urządzenia z systemem iOS. Ten precyzyjny poziom kontroli może służyć do tworzenia profesjonalnych aplikacji kamer poziomu i zapewnienia kompozycji artysty poprzez dostosowanie parametrów aparatu podczas robienia zdjęcia lub wideo.

Te kontrolki mogą być również przydatne podczas tworzenia aplikacji naukowych lub przemysłowych, gdzie wyniki są mniej ukierunkowane na poprawność lub piękno obrazu, i są bardziej ukierunkowane na wyróżnianie jakiejś funkcji lub elementu obrazu.

Obiekty przechwytywania AVFoundation

Niezależnie od tego, czy robienie obrazów wideo, czy obrazów przy użyciu aparatu na urządzeniu z systemem iOS, proces używany do przechwytywania tych obrazów jest w dużej mierze taki sam. Dotyczy to aplikacji korzystających z domyślnych kontrolek automatycznych aparatów lub korzystających z nowych kontrolek ręcznych Aparat:

Omówienie obiektów przechwytywania AVFoundation

Dane wejściowe są pobierane z elementu AVCaptureDeviceInput do elementu AVCaptureSession za pomocą elementu AVCaptureConnection. Wynikiem jest dane wyjściowe jako obraz nadal lub jako strumień wideo. Cały proces jest kontrolowany przez element AVCaptureDevice.

Dostarczone kontrolki ręczne

Za pomocą nowych interfejsów API udostępnianych przez system iOS 8 aplikacja może przejąć kontrolę nad następującymi funkcjami aparatu:

  • Ręczne ustawianie fokusu — dzięki umożliwieniu użytkownikowi końcowemu bezpośredniego kontrolowania fokusu aplikacja może zapewnić większą kontrolę nad wykonanym obrazem.
  • Ekspozycja ręczna — zapewniając ręczną kontrolę nad ekspozycją, aplikacja może zapewnić użytkownikom większą swobodę i umożliwić im osiągnięcie stylizowanego wyglądu.
  • Ręczne równoważenie bieli — białe saldo służy do dostosowywania koloru na obrazie — często, aby wyglądało to realistycznie. Różne źródła światła mają różne temperatury kolorów, a ustawienia aparatu używane do przechwytywania obrazu są dostosowywane w celu zrekompensowania tych różnic. Ponownie, zezwalając użytkownikowi na kontrolę nad białym saldem, użytkownicy mogą wprowadzać korekty, których nie można wykonać automatycznie.

System iOS 8 udostępnia rozszerzenia i ulepszenia istniejących interfejsów API systemu iOS w celu zapewnienia szczegółowej kontroli nad procesem przechwytywania obrazów.

Wymagania

Do wykonania kroków przedstawionych w tym artykule są wymagane następujące czynności:

  • Xcode 7+ i iOS 8 lub nowsze — na komputerze dewelopera muszą być zainstalowane i nowsze interfejsy API Xcode 7 i iOS 8 lub nowsze.
  • Visual Studio dla komputerów Mac — najnowsza wersja Visual Studio dla komputerów Mac powinna być zainstalowana i skonfigurowana na urządzeniu użytkownika.
  • Urządzenie z systemem iOS 8 — urządzenie z systemem iOS z najnowszą wersją systemu iOS 8. Aparat funkcji nie można przetestować w symulatorze systemu iOS.

Ogólna konfiguracja przechwytywania av

Podczas nagrywania wideo na urządzeniu z systemem iOS istnieje ogólny kod konfiguracji, który jest zawsze wymagany. Ta sekcja obejmuje minimalną konfigurację wymaganą do rejestrowania wideo z aparatu urządzenia z systemem iOS i wyświetlania tego wideo w czasie rzeczywistym w programie UIImageView.

Delegat przykładowego buforu wyjściowego

Jedną z pierwszych potrzebnych rzeczy będzie delegat do monitorowania buforu przykładowych danych wyjściowych i wyświetlania obrazu pobranego z buforu do elementu UIImageView w interfejsie użytkownika aplikacji.

Poniższa rutyna będzie monitorować przykładowy bufor i aktualizować interfejs użytkownika:

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

Dzięki tej procedurze można zmodyfikować, AppDelegate aby otworzyć sesję przechwytywania av w celu zarejestrowania kanału informacyjnego wideo na żywo.

Tworzenie sesji przechwytywania av

Sesja przechwytywania av służy do kontrolowania rejestrowania wideo na żywo z aparatu urządzenia z systemem iOS i jest wymagany do uzyskania wideo w aplikacji systemu iOS. Ponieważ przykładowa ManualCameraControl aplikacja używa sesji przechwytywania w kilku różnych miejscach, zostanie ona skonfigurowana w AppDelegate pliku i udostępniona całej aplikacji.

Wykonaj następujące czynności, aby zmodyfikować aplikacje AppDelegate i dodać niezbędny kod:

  1. AppDelegate.cs Kliknij dwukrotnie plik w Eksplorator rozwiązań, aby otworzyć go do edycji.

  2. Dodaj następujące instrukcje using na początku pliku :

    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. Dodaj następujące zmienne prywatne i obliczone właściwości do AppDelegate klasy:

    #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. Zastąpij zakończoną metodę i zmień ją na:

    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. Zapisz zmiany w pliku.

Dzięki temu kodowi można łatwo zaimplementować ręczne kontrolki Aparat na potrzeby eksperymentowania i testowania.

Ręczne ustawianie fokusu

Dzięki umożliwieniu użytkownikowi końcowemu bezpośredniego kontrolowania fokusu aplikacja może zapewnić większą kontrolę artystyczną nad wykonanym obrazem.

Na przykład profesjonalny fotograf może zmiękczyć fokus obrazu, aby osiągnąć Efekt Bokeh. Możesz też utworzyć efekt ściągania fokusu.

Dla naukowców lub pisarza aplikacji medycznych aplikacja może chcieć programowo przenieść obiektyw do eksperymentów. Tak czy inaczej nowy interfejs API umożliwia użytkownikowi końcowemu lub aplikacji przejęcie kontroli nad fokusem w czasie wykonywania obrazu.

Jak działa fokus

Przed omówieniem szczegółów kontrolowania fokusu w aplikacji systemu IOS 8. Przyjrzyjmy się, jak działa fokus na urządzeniu z systemem iOS:

Jak działa fokus na urządzeniu z systemem iOS

Światło wchodzi w obiektyw aparatu na urządzeniu z systemem iOS i koncentruje się na czujniku obrazu. Odległość obiektywu od czujnika kontroluje, gdzie znajduje się punkt centralny (obszar, w którym obraz będzie wyświetlany najostrzej) w stosunku do czujnika. Im dalej obiektyw pochodzi z czujnika, obiekty odległości wydają się najostrzejsze, a bliżej, w pobliżu obiektów wydaje się najostrzejszy.

W urządzeniu z systemem iOS obiektyw jest przesuwany bliżej lub dalej od czujnika przez magnesy i sprężyny. W rezultacie dokładne pozycjonowanie obiektywu jest niemożliwe, ponieważ będzie się różnić od urządzenia do urządzenia i może mieć wpływ na parametry, takie jak orientacja urządzenia lub wiek urządzenia i sprężyny.

Ważne terminy fokusu

W przypadku koncentracji uwagi istnieje kilka terminów, które deweloper powinien znać:

  • Głębokość pola — odległość między najbliższymi i najdalej położonymi obiektami fokusu.
  • Makro — jest to bliski koniec spektrum ostrości i jest najbliższą odległością, w której obiektyw może się skupić.
  • Infinity — jest to daleki koniec spektrum ostrości i jest najdalejszą odległością, w której obiektyw może się skupić.
  • Odległość hiperfokalna — jest to punkt w spektrum fokusu, w którym najbardziej odległy obiekt w ramce znajduje się na dalekim końcu fokusu. Innymi słowy, jest to położenie centralne, które maksymalizuje głębokość pola.
  • Pozycja obiektywu — to właśnie kontroluje wszystkie powyższe terminy. Jest to odległość obiektywu od czujnika, a tym samym kontroler ostrości.

Mając na uwadze te terminy i wiedzę, nowe ręczne kontrolki fokusu można pomyślnie zaimplementować w aplikacji systemu iOS 8.

Istniejące kontrolki koncentracji uwagi

Systemy iOS 7 i starsze wersje udostępniały istniejące kontrolki fokusu za pośrednictwem FocusModewłaściwości jako:

  • AVCaptureFocusModeLocked – Fokus jest zablokowany w jednym punkcie koncentracji uwagi.
  • AVCaptureFocusModeAutoFocus – Aparat zamiata obiektyw przez wszystkie punkty centralne, aż znajdzie ostrą koncentrację, a następnie pozostaje tam.
  • AVCaptureFocusModeContinuousAutoFocus – Aparat ustawia fokus za każdym razem, gdy wykryje stan poza fokusem.

Istniejące kontrolki udostępniały również punkt orientacyjny ustawiony za pośrednictwemFocusPointOfInterest właściwości, dzięki czemu użytkownik może naciskać, aby skupić się na określonym obszarze. Aplikacja może również śledzić ruch obiektywu, monitorując IsAdjustingFocus właściwość .

Ponadto ograniczenie zakresu zostało podane przez AutoFocusRangeRestriction właściwość jako:

  • AVCaptureAutoFocusRangeRestrictionNear – Ogranicza autofokus do pobliskich głębokości. Przydatne w sytuacjach, takich jak skanowanie kodu QR lub kodu kreskowego.
  • AVCaptureAutoFocusRangeRestrictionFar – Ogranicza autofokus do odległych głębokości. Przydatne w sytuacjach, gdy obiekty, które są znane jako nieistotne, znajdują się w polu widoku (na przykład ramka okna).

Na koniec istnieje SmoothAutoFocus właściwość, która spowalnia algorytm automatycznego koncentracji uwagi i wykonuje kroki w mniejszych przyrostach, aby uniknąć przenoszenia artefaktów podczas nagrywania wideo.

Nowe kontrolki fokusu w systemie iOS 8

Oprócz funkcji już udostępnianych przez system iOS 7 i nowszych dostępne są teraz następujące funkcje do kontrolowania fokusu w systemie iOS 8:

  • Pełna ręczna kontrola położenia obiektywu podczas blokowania fokusu.
  • Obserwacja wartości klucza pozycji obiektywu w dowolnym trybie koncentracji uwagi.

Aby zaimplementować powyższe funkcje, AVCaptureDevice klasa została zmodyfikowana w celu uwzględnienia właściwości tylko LensPosition do odczytu używanej do uzyskania bieżącej pozycji obiektywu aparatu.

Aby przejąć ręczną kontrolę nad położeniem obiektywu, urządzenie przechwytywania musi być w trybie zablokowanego koncentracji uwagi. Przykład:

CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;

Metoda SetFocusModeLocked urządzenia przechwytywania służy do dostosowywania położenia obiektywu aparatu. Opcjonalna rutyna wywołania zwrotnego może być dostarczana w celu otrzymywania powiadomień, gdy zmiana zostanie w życie. Przykład:

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

Jak pokazano w powyższym kodzie, urządzenie przechwytywania musi być zablokowane w celu skonfigurowania, zanim będzie można wprowadzić zmianę pozycji obiektywu. Prawidłowe wartości pozycji obiektywu mają od 0,0 do 1,0.

Przykład ręcznego koncentracji uwagi

Po utworzeniu ogólnego kodu konfiguracji przechwytywania av można dodać element UIViewController do scenorysu aplikacji i skonfigurować go w następujący sposób:

Kontrolka UIViewController można dodać do scenorysu aplikacji i skonfigurować tak, jak pokazano tutaj w przykładzie ręcznego koncentracji uwagi.

Widok zawiera następujące główne elementy:

  • Element UIImageView , który wyświetli kanał informacyjny wideo.
  • Element UISegmentedControl , który zmieni tryb koncentracji uwagi z automatycznego na Zablokowany.
  • Element UISlider , który pokaże i zaktualizuje bieżącą pozycję obiektywu.

Wykonaj następujące czynności, aby połączyć kontroler widoku dla ręcznego sterowania fokusem:

  1. Dodaj następujące instrukcje using:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Dodaj następujące zmienne prywatne:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Dodaj następujące obliczone właściwości:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Zastąpij metodę ViewDidLoad i dodaj następujący kod:

    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. Zastąpij metodę ViewDidAppear i dodaj następujące polecenie, aby rozpocząć nagrywanie podczas ładowania widoku:

    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. Dzięki aparatowi w trybie automatycznym suwak będzie przesuwał się automatycznie, gdy aparat dopasowuje fokus:

    Suwak zostanie automatycznie przeniesiony, gdy aparat dopasowuje fokus w tej przykładowej aplikacji

  7. Naciśnij segment Zablokowany i przeciągnij suwak położenia, aby ręcznie dostosować położenie obiektywu:

    Ręczne dostosowywanie położenia obiektywu

  8. Zatrzymaj aplikację.

Powyższy kod pokazuje, jak monitorować położenie obiektywu, gdy aparat jest w trybie automatycznym lub używa suwaka do sterowania położeniem obiektywu w trybie zablokowanym.

Ekspozycja ręczna

Ekspozycja odnosi się do jasności obrazu względem jasności źródła i zależy od tego, ile światła uderza w czujnik, jak długo i przez poziom zysku czujnika (mapowanie ISO). Zapewniając ręczną kontrolę nad ekspozycją, aplikacja może zapewnić użytkownikowi końcowemu większą swobodę i umożliwić im osiągnięcie stylizowanego wyglądu.

Korzystając z ręcznych kontrolek ekspozycji, użytkownik może zrobić obraz z nierealnie jasne do ciemnego i nastrojowego:

Przykładowy obraz przedstawiający ekspozycję z nierealistycznie jasnego na ciemny i nastrojowy

Można to zrobić automatycznie za pomocą kontroli programowej dla aplikacji naukowych lub za pomocą kontrolek ręcznych dostarczonych przez interfejs użytkownika aplikacji. Tak czy inaczej, nowe interfejsy API ekspozycji systemu iOS 8 zapewniają precyzyjną kontrolę nad ustawieniami ekspozycji aparatu.

Jak działa ekspozycja

Przed omówieniem szczegółów kontrolowania narażenia w aplikacji systemu IOS 8. Przyjrzyjmy się, jak działa ekspozycja:

Jak działa ekspozycja

Trzy podstawowe elementy, które łączą się w celu kontrolowania ekspozycji, to:

  • Szybkość migawki — jest to czas, przez jaki migawka jest otwarta, aby zapalić światło na czujnik kamery. Im krótszy czas otwarcia migawki, tym mniej światła jest wpuszczane, a chrupiący obraz jest (mniej rozmycia ruchu). Tym dłużej migawka jest otwarta, tym więcej światła jest wpuszczane i tym bardziej rozmycie ruchu, który występuje.
  • ISO Mapping — jest to termin pożyczony z fotografii filmowej i odnosi się do wrażliwości substancji chemicznych w filmie na światło. Niskie wartości ISO w folii mają mniej ziarna i drobnsze odwzorowanie kolorów; niskie wartości ISO w czujnikach cyfrowych mają mniej szumu czujnika, ale mniejszą jasność. Im wyższa wartość ISO, tym jaśniejszy obraz, ale z większym szumem czujnika. "ISO" na czujniku cyfrowym jest miarą elektronicznego zysku, a nie cech fizycznych.
  • Przysłona obiektywu — jest to rozmiar otworu obiektywu. Na wszystkich urządzeniach z systemem iOS przysłona obiektywu jest stała, więc jedyne dwie wartości, których można użyć do dostosowania ekspozycji, to Migawka Speed i ISO.

Jak działa ciągła automatyczna ekspozycja

Zanim dowiesz się, jak działa ekspozycja ręczna, warto zrozumieć, jak działa ciągłe automatyczne narażenie na działanie na urządzeniu z systemem iOS.

Jak działa ciągła automatyczna ekspozycja na urządzeniu z systemem iOS

Po pierwsze jest blok automatycznego narażenia, ma zadanie obliczania idealnej ekspozycji i jest stale karmione Metering Stats. Wykorzystuje te informacje do obliczenia optymalnej mieszaniny ISO i Shutter Speed w celu uzyskania dobrze oświetlonej sceny. Ten cykl jest określany jako pętla AE.

Jak działa zablokowane narażenie

Następnie sprawdźmy, jak działa zablokowana ekspozycja na urządzeniach z systemem iOS.

Jak działa zablokowana ekspozycja na urządzeniach z systemem iOS

Ponownie masz blok autoseksponowania, który próbuje obliczyć optymalne wartości systemów iOS i Czasu trwania. Jednak w tym trybie blok AE jest odłączony od aparatu Statystyki pomiaru.

Istniejące mechanizmy kontroli ekspozycji

System iOS 7 lub nowszy udostępnia następujące istniejące kontrolki Ekspozycja za pośrednictwem ExposureMode właściwości :

  • AVCaptureExposureModeLocked — Próbkuje scenę raz i używa tych wartości w całej scenie.
  • AVCaptureExposureModeContinuousAutoExposure — Próbkuje scenę w sposób ciągły, aby upewnić się, że jest ona dobrze oświetlona.

Można ExposurePointOfInterest go użyć do naciśnięcia, aby uwidocznić scenę, wybierając obiekt docelowy do uwidocznienia, a aplikacja może monitorować AdjustingExposure właściwość, aby zobaczyć, kiedy ekspozycja jest dostosowywana.

Nowe kontrolki ekspozycji w systemie iOS 8

Oprócz funkcji już udostępnianych przez system iOS 7 i nowszych, dostępne są teraz następujące funkcje do kontrolowania narażenia w systemie iOS 8:

  • W pełni ręczna ekspozycja niestandardowa.
  • Pobierz, ustaw i wartość klucza obserwuj iOS i Szybkość migawki (czas trwania).

Aby zaimplementować powyższe funkcje, dodano nowy AVCaptureExposureModeCustom tryb. Gdy aparat w systemie jest trybem niestandardowym, można użyć następującego kodu, aby dostosować czas trwania ekspozycji i iso:

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

W trybach Automatyczne i Zablokowane aplikacja może dostosować stronniczość automatycznej procedury ekspozycji przy użyciu następującego kodu:

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

Minimalne i maksymalne zakresy ustawień zależą od urządzenia, na którym działa aplikacja, więc nigdy nie powinny być zakodowane w kodzie. Zamiast tego użyj następujących właściwości, aby uzyskać minimalne i maksymalne zakresy wartości:

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

Jak pokazano w powyższym kodzie, urządzenie przechwytywania musi być zablokowane w celu skonfigurowania, zanim będzie można wprowadzić zmianę ekspozycji.

Przykład ekspozycji ręcznej

Po utworzeniu ogólnego kodu konfiguracji przechwytywania av można dodać element UIViewController do scenorysu aplikacji i skonfigurować go w następujący sposób:

Kontrolka UIViewController można dodać do scenorysu aplikacji i skonfigurować tak, jak pokazano w tym miejscu dla przykładu ekspozycji ręcznej.

Widok zawiera następujące główne elementy:

  • Element UIImageView , który wyświetli kanał informacyjny wideo.
  • Element UISegmentedControl , który zmieni tryb koncentracji uwagi z automatycznego na Zablokowany.
  • Cztery UISlider kontrolki, które będą wyświetlać i aktualizować przesunięcie, czas trwania, iso i stronniczy.

Wykonaj następujące czynności, aby połączyć kontroler widoku z ręczną kontrolą ekspozycji:

  1. Dodaj następujące instrukcje using:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Dodaj następujące zmienne prywatne:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    private nfloat ExposureDurationPower = 5;
    private nfloat ExposureMinimumDuration = 1.0f/1000.0f;
    #endregion
    
  3. Dodaj następujące obliczone właściwości:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Zastąpij metodę ViewDidLoad i dodaj następujący kod:

    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. Zastąpij metodę ViewDidAppear i dodaj następujące polecenie, aby rozpocząć nagrywanie podczas ładowania widoku:

    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. Dzięki aparatowi w trybie automatycznym suwaki będą przesuwać się automatycznie, gdy aparat dostosowuje ekspozycję:

    Suwaki będą przesuwać się automatycznie, gdy aparat dostosowuje ekspozycję

  7. Naciśnij segment Zablokowany i przeciągnij suwak Stronniczości, aby ręcznie dostosować stronniczość automatycznego narażenia:

    Ręczne dostosowywanie stronniczości automatycznej ekspozycji

  8. Naciśnij segment Niestandardowy i przeciągnij suwaki Czas trwania i ISO, aby ręcznie sterować ekspozycją:

    Przeciągnij suwaki Czas trwania i ISO, aby ręcznie kontrolować ekspozycję

  9. Zatrzymaj aplikację.

Powyższy kod pokazuje, jak monitorować ustawienia ekspozycji, gdy aparat jest w trybie automatycznym i jak używać suwaków do kontrolowania ekspozycji w trybie zablokowanym lub niestandardowym.

Ręczne równoważenie białych

Kontrolki White Balance umożliwiają użytkownikom dostosowanie równowagi kolosów na obrazie, aby wyglądały bardziej realistycznie. Różne źródła światła mają różne temperatury kolorów, a ustawienia aparatu używane do przechwytywania obrazu należy dostosować, aby zrekompensować te różnice. Ponownie, pozwalając użytkownikowi na kontrolę nad białym równowagą, mogą dokonać profesjonalnych korekt, że automatyczne procedury nie są w stanie osiągnąć efektów artystycznych.

Przykładowy obraz przedstawiający korekty ręcznego równoważenia bieli

Na przykład światło dzienne ma niebieską obsadę, podczas gdy żarówki wolfram mają cieplejszy, żółty pomarańczowy odcień. (Myląco, "chłodne" kolory mają wyższe temperatury kolorów niż "ciepłe" kolory. Temperatury kolorów to fizyczna miara, a nie perceptycznie.

Ludzki umysł jest bardzo dobry w kompensowaniu różnic w temperaturze kolorów, ale jest to coś, czego aparat nie może zrobić. Aparat działa poprzez zwiększenie koloru na przeciwległym spektrum, aby dostosować się do różnic kolorów.

Nowy interfejs API ekspozycji systemu iOS 8 umożliwia aplikacji przejęcie kontroli nad procesem i zapewnienie precyzyjnej kontroli nad ustawieniami białego równowagi aparatu.

Jak działa biały bilans

Przed omówieniem szczegółów kontrolowania równoważenia bieli w aplikacji systemu IOS 8. Przyjrzyjmy się szybkiej funkcji równoważenia bieli:

W badaniu percepcji kolorów CIE 1931 RGB przestrzeni kolorów i przestrzeni kolorów CIE 1931 XYZ są pierwszymi matematycznie zdefiniowanymi przestrzeniami kolorów. Zostały one utworzone przez Międzynarodową Komisję Oświetlenia (CIE) w 1931 roku.

Przestrzeń kolorów RGB CIE 1931 i CIE 1931 XYZ

Powyższy wykres przedstawia wszystkie kolory widoczne dla ludzkiego oka, od głębokiego niebieskiego do jasnego zielonego na jasnoczerwony. Dowolny punkt na diagramie można wykreślić z wartością X i Y, jak pokazano na powyższym wykresie.

Jak widać na wykresie, istnieją wartości X i Y, które można wykreślić na grafie, które byłyby poza zakresem ludzkiej wizji, a w rezultacie te kolory nie mogą być odtwarzane przez aparat fotograficzny.

Mniejsza krzywa na powyższym wykresie nazywa się Planckian Locus, która wyraża temperaturę koloru (w stopniach kelvin), z wyższymi liczbami po niebieskiej stronie (cieplejsza) i niższymi liczbami po czerwonej stronie (chłodniejsza). Są one przydatne w typowych sytuacjach oświetleniowych.

W warunkach oświetlenia mieszanego korekty równowagi białych będą musiały odbiegać od Planckian Locus, aby wprowadzić wymagane zmiany. W takich sytuacjach korekta musi zostać przesunięta na zieloną lub czerwoną/magentową stronę skali CIE.

Urządzenia z systemem iOS kompensują rzutowanie kolorów przez zwiększenie przeciwległego przyrostu kolorów. Jeśli na przykład scena ma zbyt dużo niebieskiego, to czerwony zysk zostanie wzmocniony, aby zrekompensować. Te wartości zysków są skalibrowane dla określonych urządzeń, więc są zależne od urządzenia.

Istniejące kontrolki białej równowagi

System iOS 7 lub nowszy dostarczył następujące istniejące kontrolki White Balance za pośrednictwem WhiteBalanceMode właściwości:

  • AVCapture WhiteBalance ModeLocked — Próbkuje scenę raz i używa tych wartości w całej scenie.
  • AVCapture WhiteBalance ModeContinuousAutoExposure — Próbkuje scenę w sposób ciągły, aby upewnić się, że jest ona dobrze zrównoważona.

Aplikacja może monitorować AdjustingWhiteBalance właściwość, aby sprawdzić, kiedy ekspozycja jest dostosowywana.

Nowe kontrolki white balance w systemie iOS 8

Oprócz funkcji już udostępnianych przez system iOS 7 i nowszych, dostępne są teraz następujące funkcje do kontrolowania białych sald w systemie iOS 8:

  • W pełni ręczna kontrola nad wzrostem RGB urządzenia.
  • Pobieranie, ustawianie i wartość klucza obserwuj wzrosty RGB urządzenia.
  • Obsługa białych sald przy użyciu szarej karty.
  • Procedury konwersji do i z niezależnych przestrzeni kolorów urządzenia.

Aby zaimplementować powyższe funkcje, AVCaptureWhiteBalanceGain struktura została dodana z następującymi elementami członkowskimi:

  • RedGain
  • GreenGain
  • BlueGain

Maksymalny zysk z białej MaxWhiteBalanceGain równowagi wynosi obecnie cztery (4) i może być gotowy z właściwości. Dlatego zakres prawny wynosi od jednego (1) do MaxWhiteBalanceGain (4) obecnie.

Właściwość DeviceWhiteBalanceGains może służyć do obserwowania bieżących wartości. Służy SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains do dostosowywania zysków równowagi, gdy aparat jest w zablokowanym trybie równoważenia bieli.

Procedury konwersji

Procedury konwersji zostały dodane do systemu iOS 8, aby ułatwić konwersję na i z niezależnych przestrzeni kolorów urządzenia. Aby zaimplementować procedury konwersji, AVCaptureWhiteBalanceChromaticityValues struktura została dodana z następującymi elementami członkowskimi:

  • X - jest wartością z zakresu od 0 do 1.
  • Y - jest wartością z zakresu od 0 do 1.

Dodano AVCaptureWhiteBalanceTemperatureAndTintValues również strukturę z następującymi elementami członkowskimi:

  • Temperature - jest wartością zmiennoprzecinkową w stopniach Kelvin.
  • Tint - jest przesunięciem z zielonego lub magenta z zakresu od 0 do 150 z wartościami dodatnimi w kierunku zielonym i ujemnym w kierunku magenta.

CaptureDevice.GetTemperatureAndTintValuesUżyj metod iCaptureDevice.GetDeviceWhiteBalanceGains, aby przekonwertować między temperaturą a odcieniem, chromatycją i RGB zyskują przestrzenie kolorów.

Uwaga

Procedury konwersji są dokładniejsze, im bliżej wartości, która ma zostać przekonwertowana, jest do Locus Planckian.

Obsługa szarej karty

Firma Apple używa terminu Gray World, aby odwoływać się do obsługi szarej karty wbudowanej w system iOS 8. Dzięki niej użytkownik może skupić się na fizycznej szarej karcie, która obejmuje co najmniej 50% środka ramki i używa jej do dostosowywania białego salda. Celem szarej karty jest osiągnięcie bieli, która wydaje się neutralna.

Można to zaimplementować w aplikacji, monitując użytkownika o umieszczenie fizycznej szarej karty przed kamerą, monitorowanie GrayWorldDeviceWhiteBalanceGains właściwości i oczekiwanie na osiedlenie się wartości.

Następnie aplikacja zablokuje zyski z białej równowagi dla SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains metody przy użyciu wartości z GrayWorldDeviceWhiteBalanceGains właściwości, aby zastosować zmiany.

Urządzenie przechwytywania musi być zablokowane w celu skonfigurowania, zanim będzie można wprowadzić zmianę w usłudze White Balance.

Przykład ręcznego równoważenia bieli

Po utworzeniu ogólnego kodu konfiguracji przechwytywania av można dodać element UIViewController do scenorysu aplikacji i skonfigurować go w następujący sposób:

Kontrolka UIViewController można dodać do scenorysu aplikacji i skonfigurować tak, jak pokazano tutaj w przykładzie ręcznego równoważenia bieli.

Widok zawiera następujące główne elementy:

  • Element UIImageView , który wyświetli kanał informacyjny wideo.
  • Element UISegmentedControl , który zmieni tryb koncentracji uwagi z automatycznego na Zablokowany.
  • Dwie UISlider kontrolki, które będą wyświetlać i aktualizować temperaturę i odcień.
  • Element UIButton używany do próbkowania szarej karty (szarego świata) i ustawiania białej równowagi przy użyciu tych wartości.

Wykonaj następujące czynności, aby połączyć kontroler widoku z ręcznym sterowaniem równoważeniem bieli:

  1. Dodaj następujące instrukcje using:

    using System;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using System.Timers;
    
  2. Dodaj następujące zmienne prywatne:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Dodaj następujące obliczone właściwości:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Dodaj następującą prywatną metodę, aby ustawić nową białą równowagę temperatury i odcienia:

    #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. Zastąpij metodę ViewDidLoad i dodaj następujący kod:

    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. Zastąpij metodę ViewDidAppear i dodaj następujące polecenie, aby rozpocząć nagrywanie podczas ładowania widoku:

    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. Zapisz zmiany w kodzie i uruchom aplikację.

  8. Dzięki aparatowi w trybie automatycznym suwaki będą automatycznie przesuwane, gdy aparat dopasowuje biały bilans:

    Suwaki będą przesuwane automatycznie, gdy aparat dopasowuje biały bilans

  9. Naciśnij segment Zablokowany i przeciągnij suwaki Temp i Tint, aby ręcznie dostosować saldo białych:

    Przeciągnij suwaki Temp i Tint, aby ręcznie dostosować saldo białych

  10. Po wybraniu nadal zaznaczonego segmentu Blokada umieść fizyczną szarą kartę przed aparatem i naciśnij przycisk Szara karta, aby dostosować biały bilans do szarego świata:

    Naciśnij przycisk Szara karta, aby dostosować biały bilans do szarego świata

  11. Zatrzymaj aplikację.

Powyższy kod pokazuje, jak monitorować ustawienia równoważenia bieli, gdy aparat jest w trybie automatycznym lub używa suwaków do kontrolowania równowagi białej, gdy znajduje się w trybie zablokowanym.

Przechwytywanie w nawiasie kwadratowym

Przechwytywanie w nawiasach opiera się na ustawieniach przedstawionych powyżej w obszarze Ręczne kontrolki Aparat i umożliwia aplikacji przechwytywanie chwili w czasie na różne sposoby.

Mówiąc po prostu, przechwytywanie nawiasów jest serią obrazów wykonanych z różnych ustawień z obrazu na obraz.

Jak działa przechwytywanie w nawiasach kwadratowych

Korzystając z przechwytywania w nawiasach w systemie iOS 8, aplikacja może wstępnie ustawić serię ręcznych kontrolek Aparat, wydać jedno polecenie i mieć bieżącą scenę zwrócić serię obrazów dla każdego z ręcznych ustawień wstępnych.

Podstawy przechwytywania w nawiasach

Ponownie, Nawiasy przechwytywania jest serią obrazów wykonanych z różnymi ustawieniami od obrazu do obrazu. Dostępne typy przechwytywania w nawiasach to:

  • Nawias automatycznej ekspozycji — w którym wszystkie obrazy mają różną ilość stronniczą.
  • Ręczny nawias ekspozycji — gdzie wszystkie obrazy mają różną szybkość migawki (czas trwania) i ilość ISO.
  • Prosty nawias pękowy — seria zdjęć wykonanych w krótkim odstępie czasu.

Nowe kontrolki przechwytywania w nawiasach w systemie iOS 8

Wszystkie polecenia przechwytywania w nawiasach AVCaptureStillImageOutput są implementowane w klasie . CaptureStillImageBracketUżyj metody , aby pobrać serię obrazów z daną tablicą ustawień.

Zaimplementowano dwie nowe klasy do obsługi ustawień:

  • AVCaptureAutoExposureBracketedStillImageSettings – Ma jedną właściwość , ExposureTargetBiasużywaną do ustawiania stronniczość dla nawiasu ekspozycji automatycznej.
  • AVCaptureManualExposureBracketedStillImageSettings – Ma dwie właściwości i ExposureDurationISO, używane do ustawiania prędkości migawki i ISO dla ręcznego nawiasu ekspozycji.

Kontrolki przechwytywania w nawiasach i nie

Czy

Poniżej przedstawiono listę rzeczy, które należy wykonać w przypadku używania kontrolek Przechwytywanie w nawiasach w systemie iOS 8:

  • Przygotuj aplikację do najgorszej sytuacji przechwytywania przypadków, wywołując metodę PrepareToCaptureStillImageBracket .
  • Załóżmy, że przykładowe bufory będą pochodzić z tej samej puli udostępnionej.
  • Aby zwolnić pamięć przydzieloną przez poprzednie wywołanie przygotowywania, wywołaj PrepareToCaptureStillImageBracket ją ponownie i wyślij do niej tablicę jednego obiektu.

Zakazów

Poniżej przedstawiono listę rzeczy, które nie powinny być wykonywane w przypadku używania kontrolek Przechwytywanie w nawiasach w systemie iOS 8:

  • Nie mieszaj typów ustawień przechwytywania w nawiasach w ramach pojedynczego przechwytywania.
  • Nie żądaj więcej niż MaxBracketedCaptureStillImageCount obrazów w ramach pojedynczego przechwytywania.

Szczegóły przechwytywania w nawiasach

Podczas pracy z przechwytywaniem w nawiasach w systemie iOS 8 należy wziąć pod uwagę następujące szczegóły:

  • Ustawienia nawiasów tymczasowo zastępują AVCaptureDevice ustawienia.
  • Ustawienia stabilizacji obrazu i flash są ignorowane.
  • Wszystkie obrazy muszą używać tego samego formatu wyjściowego (jpeg, png itp.)
  • Podgląd wideo może usuwać ramki.
  • Przechwytywanie w nawiasach jest obsługiwane na wszystkich urządzeniach zgodnych z systemem iOS 8.

Mając na uwadze te informacje, przyjrzyjmy się przykładowi użycia funkcji Przechwytywanie w nawiasach kwadratowych w systemie iOS 8.

Przykład przechwytywania nawiasów kwadratowych

Po utworzeniu ogólnego kodu konfiguracji przechwytywania av można dodać element UIViewController do scenorysu aplikacji i skonfigurować go w następujący sposób:

Element UIViewController można dodać do scenorysu aplikacji i skonfigurować tak, jak pokazano poniżej przykład przechwytywania nawiasów kwadratowych.

Widok zawiera następujące główne elementy:

  • Element UIImageView , który wyświetli kanał informacyjny wideo.
  • Trzy UIImageViews , które będą wyświetlać wyniki przechwytywania.
  • A UIScrollView do domu kanału informacyjnego wideo i wyświetleń wyników.
  • Element UIButton używany do przechwytywania w nawiasach z pewnymi ustawieniami wstępnymi.

Wykonaj następujące czynności, aby połączyć kontroler widoku dla przechwytywania w nawiasach:

  1. Dodaj następujące instrukcje using:

    using System;
    using System.Drawing;
    using Foundation;
    using UIKit;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using AVFoundation;
    using CoreVideo;
    using CoreMedia;
    using CoreGraphics;
    using CoreFoundation;
    using CoreImage;
    
  2. Dodaj następujące zmienne prywatne:

    #region Private Variables
    private NSError Error;
    private List<UIImageView> Output = new List<UIImageView>();
    private nint OutputIndex = 0;
    #endregion
    
  3. Dodaj następujące obliczone właściwości:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    #endregion
    
  4. Dodaj następującą metodę prywatną, aby utworzyć wymagane widoki obrazów wyjściowych:

    #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. Zastąpij metodę ViewDidLoad i dodaj następujący kod:

    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. Zastąpij metodę ViewDidAppear i dodaj następujący kod:

    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. Zapisz zmiany w kodzie i uruchom aplikację.

  8. Utwórz ramkę sceny i naciśnij przycisk Przechwytywanie nawiasu:

    Wyramuj scenę i naciśnij przycisk Przechwyć nawias kwadratowy

  9. Przesuń palcem w prawo do lewej, aby wyświetlić trzy obrazy wykonane przez przechwytywanie w nawiasach:

    Przesuń palcem w prawo do lewej, aby wyświetlić trzy obrazy wykonane przez przechwytywanie w nawiasie kwadratowym

  10. Zatrzymaj aplikację.

Powyższy kod pokazuje, jak skonfigurować i pobrać przechwytywanie w nawiasach ekspozycji automatycznej w systemie iOS 8.

Podsumowanie

W tym artykule omówiliśmy wprowadzenie do nowych kontrolek ręcznych Aparat udostępnianych przez system iOS 8 i omówiliśmy podstawowe informacje o tym, co robią i jak działają. Nadaliśmy przykłady ręcznego koncentracji uwagi, ekspozycji ręcznej i ręcznego równoważenia bieli. Na koniec przedstawiono przykład przedstawiający przechwytywanie w nawiasach przy użyciu wcześniej omówionego ręcznego Aparat kontrolek