Ręczne kontrolki aparatu w środowisku Xamarin.iOS
Kontrolki ręcznej kamery dostarczone 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 automatycznych kontrolek aparatu lub tych, które korzystają z nowych kontrolek aparatu ręcznego:
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. Nie można przetestować funkcji aparatu 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:
AppDelegate.cs
Kliknij dwukrotnie plik w Eksplorator rozwiązań, aby otworzyć go do edycji.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;
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
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; }
Zapisz zmiany w pliku.
Dzięki temu kodowi można łatwo zaimplementować ręczne kontrolki aparatu 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:
Ś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 FocusMode
wł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:
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:
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;
Dodaj następujące zmienne prywatne:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
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
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(); }; }
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 (); } }
Dzięki aparatowi w trybie automatycznym suwak będzie przesuwał się automatycznie, gdy aparat dopasowuje fokus:
Naciśnij segment Zablokowany i przeciągnij suwak położenia, aby ręcznie dostosować położenie obiektywu:
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:
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:
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.
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.
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:
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:
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;
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
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
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(); }; }
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 (); } }
Dzięki aparatowi w trybie automatycznym suwaki będą przesuwać się automatycznie, gdy aparat dostosowuje ekspozycję:
Naciśnij segment Zablokowany i przeciągnij suwak Stronniczości, aby ręcznie dostosować stronniczość automatycznego narażenia:
Naciśnij segment Niestandardowy i przeciągnij suwaki Czas trwania i ISO, aby ręcznie sterować ekspozycją:
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.
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.
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.GetTemperatureAndTintValues
Uż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:
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:
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;
Dodaj następujące zmienne prywatne:
#region Private Variables private NSError Error; private bool Automatic = true; #endregion
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
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
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 (); } }; }
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 (); } }
Zapisz zmiany w kodzie i uruchom aplikację.
Dzięki aparatowi w trybie automatycznym suwaki będą automatycznie przesuwane, gdy aparat dopasowuje biały bilans:
Naciśnij segment Zablokowany i przeciągnij suwaki Temp i Tint, aby ręcznie dostosować saldo białych:
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:
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 kontrolkach ręcznej kamery 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.
Korzystając z przechwytywania nawiasów w systemie iOS 8, aplikacja może wstępnie ustawić serię ręcznych kontrolek aparatu, 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 . CaptureStillImageBracket
Uż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ść ,ExposureTargetBias
używaną do ustawiania stronniczość dla nawiasu ekspozycji automatycznej.AVCaptureManual
ExposureBracketedStillImageSettings
– Ma dwie właściwości iExposureDuration
ISO
, 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 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:
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:
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;
Dodaj następujące zmienne prywatne:
#region Private Variables private NSError Error; private List<UIImageView> Output = new List<UIImageView>(); private nint OutputIndex = 0; #endregion
Dodaj następujące obliczone właściwości:
#region Computed Properties public AppDelegate ThisApp { get { return (AppDelegate)UIApplication.SharedApplication.Delegate; } } #endregion
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
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(); }); }; }
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 (); } }
Zapisz zmiany w kodzie i uruchom aplikację.
Utwórz ramkę sceny i naciśnij przycisk Przechwytywanie nawiasu:
Przesuń palcem w prawo do lewej, aby wyświetlić trzy obrazy wykonane przez przechwytywanie w nawiasach:
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 ręcznych kontrolek aparatów dostarczonych 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ówionych kontrolek aparatu ręcznego