Поделиться через


Элементы управления Камера вручную в Xamarin.iOS

Элементы управления вручную Камера, предоставляемые AVFoundation Framework в iOS 8, позволяют мобильному приложению полностью контролировать камеру устройства iOS. Этот точный уровень управления можно использовать для создания приложений камеры профессионального уровня и предоставления артистских композиций путем настройки параметров камеры при принятии по-прежнему изображения или видео.

Эти элементы управления также могут быть полезными при разработке научных или промышленных приложений, где результаты менее ориентированы на правильность или красоту изображения, а также ориентированы на выделение некоторых признаков или элементов изображения.

Объекты захвата AVFoundation

Независимо от того, принимает ли видео или все еще изображения с помощью камеры на устройстве iOS, процесс, используемый для записи этих изображений, в значительной степени совпадает. Это верно для приложений, использующих автоматические элементы управления камеры по умолчанию или те, которые используют новые элементы управления ручной Камера:

Обзор объектов записи AVFoundation

Входные данные взяты из AVCaptureDeviceInputAVCaptureSession объекта в пути AVCaptureConnection. Результатом является либо вывод в виде по-прежнему изображения, либо в виде видеопотока. Весь процесс управляется с помощью AVCaptureDevice.

Предоставленные вручную элементы управления

Используя новые API, предоставляемые iOS 8, приложение может контролировать следующие функции камеры:

  • Фокус вручную. Благодаря тому, что конечный пользователь может напрямую контролировать фокус, приложение может обеспечить больше контроля над изображением.
  • Экспозиция вручную . Предоставляя ручной контроль над экспозицией, приложение может обеспечить больше свободы для пользователей и позволить им достичь стилизованного вида.
  • Ручной баланс белого баланса — белый баланс используется для настройки цвета в изображении— часто, чтобы сделать его реалистичным. Различные источники света имеют разные цветовые температуры, а параметры камеры, используемые для захвата изображения, корректируются для компенсации этих различий. Опять же, позволяя пользователю контролировать белый баланс, пользователи могут вносить корректировки, которые не могут быть выполнены автоматически.

iOS 8 предоставляет расширения и улучшения существующих API iOS, чтобы обеспечить этот подробный контроль над процессом захвата изображений.

Требования

Для выполнения описанных в этой статье действий необходимо выполнить следующие действия.

  • Xcode 7+ и iOS 8 или более поздних версий — на компьютере разработчика необходимо установить и настроить интерфейсы API Apple Xcode 7 и iOS 8 или более поздних версий.
  • Visual Studio для Mac — последняя версия Visual Studio для Mac должна быть установлена и настроена на устройстве пользователя.
  • Устройство iOS 8 — устройство iOS под управлением последней версии iOS 8. Камера функции нельзя протестировать в симуляторе iOS.

Общая настройка записи AV

При записи видео на устройстве iOS существует некоторый общий код установки, который всегда требуется. В этом разделе описана минимальная настройка, необходимая для записи видео с камеры устройства iOS и отображения видео в UIImageViewрежиме реального времени.

Делегат буфера выходных данных

Одним из первых вещей будет делегат для мониторинга буфера выходных данных образца и отображения изображения, полученного из буфера UIImageView в пользовательском интерфейсе приложения.

Следующая подпрограмма будет отслеживать пример буфера и обновлять пользовательский интерфейс:

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

С помощью этой подпрограммы можно изменить, AppDelegate чтобы открыть сеанс записи av для записи видеотрансляций.

Создание сеанса записи AV

Сеанс записи AV используется для управления записью видеотрансляций с камеры устройства iOS и требуется для получения видео в приложение iOS. Так как пример ManualCameraControl приложения использует сеанс записи в нескольких разных местах, он будет настроен в приложении и доступен для AppDelegate всего приложения.

Выполните следующие действия, чтобы изменить приложение AppDelegate и добавить необходимый код:

  1. Дважды щелкните AppDelegate.cs файл в Обозреватель решений, чтобы открыть его для редактирования.

  2. Добавьте в начало файла следующие инструкции 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;
    
  3. Добавьте в класс следующие частные переменные и вычисляемых свойств AppDelegate :

    #region Private Variables
    private NSError Error;
    #endregion
    
    #region Computed Properties
    public override UIWindow Window {get;set;}
    public bool CameraAvailable { get; set; }
    public AVCaptureSession Session { get; set; }
    public AVCaptureDevice CaptureDevice { get; set; }
    public OutputRecorder Recorder { get; set; }
    public DispatchQueue Queue { get; set; }
    public AVCaptureDeviceInput Input { get; set; }
    #endregion
    
  4. Переопределите готовый метод и измените его на:

    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. Сохраните изменения в файле.

С помощью этого кода можно легко реализовать элементы управления Камера вручную для экспериментирования и тестирования.

Фокус вручную

Позволяя конечному пользователю напрямую контролировать фокус, приложение может обеспечить более художественный контроль над изображением.

Например, профессиональный фотограф может смягчить фокус изображения для достижения эффекта Боке. Или создайте эффект вытягивания фокуса.

Для ученых или писателя медицинских приложений приложение может потребоваться программно переместить объектив вокруг экспериментов. В любом случае новый API позволяет пользователю или приложению управлять фокусом во время создания изображения.

Принцип работы фокуса

Перед обсуждением сведений об управлении фокусом в приложении IOS 8. Давайте рассмотрим, как фокус работает на устройстве iOS:

Как фокус работает на устройстве iOS

Свет входит в объектив камеры на устройстве iOS и сосредоточен на датчике изображения. Расстояние объектива от датчика управления, где фокус-точка (область, в которой изображение будет отображаться самым острым) находится в связи с датчиком. Чем дальше объектив от датчика, объекты расстояния кажутся самыми острыми и ближе, рядом с объектами кажутся самыми острыми.

В устройстве iOS объектив перемещается ближе или дальше от датчика магнитами и спрингами. В результате точное расположение объектива невозможно, так как оно будет зависеть от устройства к устройству и может влиять на такие параметры, как ориентация устройства или возраст устройства и весной.

Важные термины фокуса

При работе с фокусом есть несколько терминов, с которыми должен ознакомиться разработчик:

  • Глубина поля — расстояние между ближайшими и самыми дальними объектами в фокусе.
  • Макрос - Это ближайший конец спектра фокуса и является ближайшим расстоянием, на котором объектив может сосредоточиться.
  • Бесконечность - это дальний конец спектра фокуса и является самым дальним расстоянием, на котором объектив может сосредоточиться.
  • Гиперфокальное расстояние — это точка в спектре фокуса, где самый дальний объект в кадре находится только в конце фокуса. Другими словами, это фокусовое положение, которое максимизирует глубину поля.
  • Положение объектива — это то, что управляет всеми выше другими терминами. Это расстояние от датчика и таким образом контроллер фокуса.

Учитывая эти термины и знания, новые элементы управления фокусом вручную можно успешно реализовать в приложении iOS 8.

Существующие элементы управления фокусом

IOS 7 и более ранние версии предоставляют существующие элементы управления фокусом через FocusModeсвойство:

  • AVCaptureFocusModeLocked — фокус заблокирован в одной точке фокуса.
  • AVCaptureFocusModeAutoFocus - Камера подметает объектив через все фокусные точки, пока он не находит острый фокус, а затем остается там.
  • AVCaptureFocusModeContinuousAutoFocus — камера перенаправляется всякий раз, когда обнаруживает состояние вне фокуса.

Существующие элементы управления также предоставили точку интереса к набору черезFocusPointOfInterest свойство, чтобы пользователь смог коснуться, чтобы сосредоточиться на определенной области. Приложение также может отслеживать движение объектива IsAdjustingFocus , отслеживая свойство.

Кроме того, ограничение диапазона было предоставлено свойством AutoFocusRangeRestriction следующим образом:

  • AVCaptureAutoFocusRangeRestrictionNear — ограничивает автофокус до близлежащих глубин. Полезно в таких ситуациях, как сканирование QR-кода или штрихкода.
  • AVCaptureAutoFocusRangeRestrictionFar — ограничивает автофокус до удаленных глубин. Полезно в ситуациях, когда объекты, которые, как известно, не имеют значения, находятся в поле представления (например, рамка окна).

Наконец, есть SmoothAutoFocus свойство, которое замедляет алгоритм автоматического фокуса и выполняет его в меньших добавках, чтобы избежать перемещения артефактов при записи видео.

Новые элементы управления фокусом в iOS 8

Помимо функций, уже предоставляемых iOS 7 и более поздних версий, теперь доступны следующие функции для управления фокусом в iOS 8.

  • Полное управление положением объектива при блокировке фокуса вручную.
  • Наблюдение за положением объектива в любом режиме фокуса.

Чтобы реализовать указанные выше функции, класс был изменен, чтобы включить свойство только LensPosition для чтения, AVCaptureDevice используемое для получения текущей позиции объектива камеры.

Чтобы управлять положением объектива вручную, устройство записи должно находиться в режиме заблокированного фокуса. Пример:

CaptureDevice.FocusMode = AVCaptureFocusMode.Locked;

Метод SetFocusModeLocked устройства захвата используется для настройки положения объектива камеры. Необязательный подпрограмма обратного вызова может быть предоставлена для получения уведомлений, когда изменения вступает в силу. Пример:

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

Как показано в приведенном выше коде, устройство записи должно быть заблокировано для настройки, прежде чем изменить положение объектива. Допустимые значения положения объектива : от 0,0 до 1.0.

Пример фокусировки вручную

С помощью кода UIViewController установки общей программы записи AV можно добавить в раскадровку приложения и настроить следующим образом:

UiViewController можно добавить в приложения Storyboard и настроить его, как показано здесь для примера фокусировки вручную.

Представление содержит следующие основные элементы:

  • Будет UIImageView отображаться видеотрансляции.
  • Значение UISegmentedControl , которое изменит режим фокусировки с автоматического на заблокированное.
  • Объект UISlider , который будет отображать и обновлять текущую позицию объектива.

Выполните следующие действия, чтобы подключить контроллер представления для управления фокусом вручную:

  1. Добавьте операторы 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. Добавьте следующие частные переменные:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Добавьте следующие вычисляемые свойства:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Переопределите ViewDidLoad метод и добавьте следующий код:

    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. Переопределите ViewDidAppear метод и добавьте следующее, чтобы начать запись при загрузке представления:

    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. При использовании камеры в автоматическом режиме ползунок будет автоматически перемещаться по мере настройки фокуса камеры:

    Ползунок будет автоматически перемещаться по мере настройки фокуса камеры в этом примере приложения

  7. Коснитесь заблокированного сегмента и перетащите ползунок положения, чтобы настроить положение объектива вручную:

    Настройка положения объектива вручную

  8. Остановите приложение.

Приведенный выше код показал, как отслеживать положение объектива, когда камера находится в автоматическом режиме или использовать ползунок для управления положением объектива, когда он находится в режиме блокировки.

Воздействие вручную

Экспозиция относится к яркости изображения относительно исходной яркости и определяется тем, сколько света попадает в датчик, на сколько времени и на уровне получения датчика (сопоставление ISO). Предоставляя ручной контроль над экспозицией, приложение может обеспечить больше свободы для конечного пользователя и позволить им достичь стилизованного внешнего вида.

С помощью элементов управления экспозицией вручную пользователь может получить изображение от нереалистично яркого до темного и настроенного:

Пример изображения, показывающее экспозицию от нереалистично яркого до темного и настроенного

Опять же, это можно сделать автоматически с помощью программного управления для научных приложений или с помощью ручных элементов управления, предоставляемых пользовательским интерфейсом приложений. В любом случае новые API экспозиции iOS 8 обеспечивают точный контроль над параметрами экспозиции камеры.

Принцип работы экспозиции

Перед обсуждением сведений об управлении воздействием в приложении IOS 8. Давайте рассмотрим, как работает экспозиция:

Принцип работы экспозиции

Ниже приведены три основных элемента, которые объединяются для контроля воздействия:

  • Скорость затвора — это продолжительность времени, когда затвор открыт, чтобы позволить свету на датчик камеры. Чем короче время открытия затвора, тем меньше света впустит и хрустящий изображение является (меньше размытия движения). Чем дольше затвор открыт, тем больше света впустит и чем больше размытия движения, что происходит.
  • Сопоставление ISO — это термин, заимствованный из фотографии пленки и относится к чувствительности химических веществ в пленке к свету. Низкие значения ISO в пленке имеют меньше зерна и более тонкого воспроизведения цветов; низкие значения ISO на цифровых датчиках имеют меньше шума датчика, но меньше яркости. Чем выше значение ISO, тем ярче изображение, но с большим шумом датчика. "ISO" на цифровом датчике является мерой электронного получения, а не физической функции.
  • Диафрагма объектива — это размер открывающегося объектива. На всех устройствах iOS диафрагма объектива фиксирована, поэтому единственными двумя значениями, которые можно использовать для настройки экспозиции, являются скорость затвора и ISO.

Как работает непрерывная автоматическая экспозиция

Прежде чем узнать, как работает ручное воздействие, рекомендуется понять, как работает непрерывная автоматическая экспозиция на устройстве iOS.

Как работает непрерывная автоматическая экспозиция на устройстве iOS

Во-первых, это блок автоматической экспозиции, он имеет задание вычисления идеальной экспозиции и постоянно кормится статистикой измерения. Эта информация используется для вычисления оптимальной смеси ISO и скорости затвора, чтобы получить сцену хорошо освещенной. Этот цикл называется циклом AE.

Как работает заблокированная экспозиция

Далее давайте рассмотрим, как заблокированная экспозиция работает на устройствах iOS.

Как работает заблокированная экспозиция на устройствах iOS

Опять же, у вас есть блок автоматического воздействия, который пытается вычислить оптимальные значения iOS и Duration. Однако в этом режиме блок AE отключен от подсистемы статистики измерения.

Существующие элементы управления экспозицией

IOS 7 и более поздних версий предоставьте следующие существующие элементы управления экспозицией ExposureMode с помощью свойства:

  • AVCaptureExposureModeLocked — примеры сцены один раз и используют эти значения во всей сцене.
  • AVCaptureExposureModeContinuousAutoExposure — примеры сцены непрерывно, чтобы убедиться, что она хорошо освещена.

Можно ExposurePointOfInterest использовать для касания для предоставления сцены, выбрав целевой объект для предоставления, и приложение может отслеживать AdjustingExposure свойство, чтобы увидеть, когда настраивается экспозиция.

Новые элементы управления экспозицией в iOS 8

Помимо функций, уже предоставляемых iOS 7 и более поздних версий, теперь доступны следующие функции для управления экспозицией в iOS 8:

  • Полностью настраиваемое воздействие вручную.
  • Получение, установка и ключевое значение отслеживают скорость ввода-вывода и скорость затвора (длительность).

Для реализации указанных выше функций добавлен новый AVCaptureExposureModeCustom режим. Если камера находится в пользовательском режиме, можно использовать следующий код для настройки длительности экспозиции и ISO:

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

В режимах авто и блокировки приложение может настроить предвзятость подпрограммы автоматического воздействия с помощью следующего кода:

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

Минимальные и максимальные диапазоны параметров зависят от устройства, на котором работает приложение, поэтому они никогда не должны быть жестко закодированы. Вместо этого используйте следующие свойства, чтобы получить минимальные и максимальные диапазоны значений:

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

Как показано в приведенном выше коде, устройство записи должно быть заблокировано для настройки перед изменением воздействия.

Пример экспозиции вручную

С помощью кода UIViewController установки общей программы записи AV можно добавить в раскадровку приложения и настроить следующим образом:

UiViewController можно добавить в раскадровку приложений и настроить его, как показано здесь для примера экспозиции вручную.

Представление содержит следующие основные элементы:

  • Будет UIImageView отображаться видеотрансляции.
  • Значение UISegmentedControl , которое изменит режим фокусировки с автоматического на заблокированное.
  • Четыре UISlider элемента управления, отображающие и обновляющие смещение, длительность, ISO и предвзятость.

Выполните следующие действия, чтобы подключить контроллер представления для ручного управления экспозицией.

  1. Добавьте операторы 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. Добавьте следующие частные переменные:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    private nfloat ExposureDurationPower = 5;
    private nfloat ExposureMinimumDuration = 1.0f/1000.0f;
    #endregion
    
  3. Добавьте следующие вычисляемые свойства:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Переопределите ViewDidLoad метод и добавьте следующий код:

    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. Переопределите ViewDidAppear метод и добавьте следующее, чтобы начать запись при загрузке представления:

    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. При использовании камеры в автоматическом режиме ползунки будут автоматически перемещаться по мере настройки экспозиции камеры:

    Ползунки будут автоматически перемещаться по мере настройки экспозиции камеры

  7. Коснитесь заблокированного сегмента и перетащите ползунок Предвзятости, чтобы настроить предвзятость автоматического воздействия вручную:

    Настройка предвзятости автоматического воздействия вручную

  8. Коснитесь пользовательского сегмента и перетащите ползунки "Длительность" и "ISO", чтобы вручную управлять экспозицией:

    Перетащите ползунки

  9. Остановите приложение.

Приведенный выше код показал, как отслеживать параметры экспозиции, когда камера находится в автоматическом режиме, и как использовать ползунки для управления экспозицией, когда она находится в заблокированных или настраиваемых режимах.

Балансировка белого трафика вручную

Элементы управления "Белый баланс" позволяют пользователям настраивать баланс колозера на изображении, чтобы сделать их более реалистичным. Различные источники света имеют разные цветовые температуры, а параметры камеры, используемые для захвата изображения, должны быть скорректированы для компенсации этих различий. Опять же, позволяя пользователю контролировать белый баланс, они могут внести профессиональные корректировки, что автоматические подпрограммы не способны достичь художественных эффектов.

Пример изображения с корректировками ручного баланса

Например, дневной свет имеет синеватый литый, в то время как тюнгстен накаливания свет имеет более теплый, желтый оранжевый оттенок. (Запутанно, "холодные" цвета имеют более высокие температуры цвета, чем "теплые" цвета. Температура цвета является физической мерой, а не перцептуальной.)

Человеческий ум очень хорошо компенсирует различия в цветовой температуре, но это то, что камера не может сделать. Камера работает путем повышения цвета на противоположном спектре, чтобы настроить различия в цвете.

Новый API экспозиции iOS 8 позволяет приложению контролировать процесс и обеспечивать точное управление параметрами баланса камеры.

Как работает баланс белого цвета

Перед обсуждением сведений о контроле баланса в приложении IOS 8. Давайте рассмотрим, как работает баланс белого цвета:

В исследовании восприятия цвета пространство цветов CIE 1931 RGB и CIE 1931 XYZ цветового пространства являются первыми математически определенными цветовыми пространствами. Они были созданы Международной комиссией по освещению (CIE) в 1931 году.

Цветовое пространство RGB CIE 1931 и цветовое пространство CIE 1931 XYZ

На приведенной выше диаграмме показаны все цвета, видимые человеческому глазу, от глубокого синего до ярко-зеленого до ярко-красного. Любую точку на схеме можно отобразить со значением X и Y, как показано на приведенном выше графике.

Как видно на графике, существуют значения X и Y, которые могут быть выложены на графе, который будет находиться за пределами диапазона человеческого зрения, и в результате эти цвета не могут быть воспроизведены камерой.

Меньшая кривая на приведенной выше диаграмме называется Планкским Локусом, который выражает цветовую температуру (в градусах кельвин), с более высокими числами на синей стороне (горячим) и более низкими числами на красной стороне (прохладнее). Это полезно для типичных ситуаций освещения.

В условиях смешанного освещения корректировки баланса белого баланса необходимо будет отклонить от Планкского локуса, чтобы внести необходимые изменения. В таких ситуациях корректировка должна быть перемещена на зеленую или красную или пурпурную сторону шкалы CIE.

Устройства iOS компенсируют цветовые приведение путем повышения противоположного получения цвета. Например, если сцена имеет слишком много синего цвета, то красный выигрыш будет повышен, чтобы компенсировать. Эти значения получения определяются для конкретных устройств, поэтому они зависят от устройств.

Существующие элементы управления балансом белого цвета

IOS 7 и более поздних версий предоставил следующие существующие элементы управления White Balance через WhiteBalanceMode свойство:

  • AVCapture WhiteBalance ModeLocked — примеры сцены один раз и использование этих значений во всей сцене.
  • AVCapture WhiteBalance ModeContinuousAutoExposure — примеры сцены непрерывно, чтобы убедиться, что она хорошо сбалансирована.

Приложение может отслеживать AdjustingWhiteBalance свойство, чтобы узнать, когда настраивается экспозиция.

Новые элементы управления "Белый баланс" в iOS 8

Помимо функций, уже предоставляемых iOS 7 и более поздних версий, теперь доступны следующие функции для управления белым балансом в iOS 8.

  • Полностью ручное управление преимуществами RGB устройства.
  • Получение, установка и ключевое значение отслеживают преимущества RGB устройства.
  • Поддержка белого баланса с помощью серой карточки.
  • Подпрограммы преобразования в независимые от устройства цветовые пространства и из нее.

Для реализации указанных выше функций AVCaptureWhiteBalanceGain структура была добавлена со следующими элементами:

  • RedGain
  • GreenGain
  • BlueGain

Максимальное увеличение баланса в настоящее время составляет четыре (4) и может быть готово из MaxWhiteBalanceGain свойства. Таким образом, юридический диапазон составляет от одного (1) до MaxWhiteBalanceGain (4) в настоящее время.

Свойство DeviceWhiteBalanceGains можно использовать для наблюдения за текущими значениями. Используйте SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains для настройки баланса, когда камера находится в заблокированном режиме балансировки белого баланса.

Подпрограммы преобразования

Подпрограммы преобразования были добавлены в iOS 8, чтобы помочь в преобразовании и из нее независимых цветовых пространств устройств. Для реализации подпрограмм AVCaptureWhiteBalanceChromaticityValues преобразования структура была добавлена со следующими элементами:

  • X — значение от 0 до 1.
  • Y — значение от 0 до 1.

Структура AVCaptureWhiteBalanceTemperatureAndTintValues также добавлена со следующими элементами:

  • Temperature — значение с плавающей запятой в градусах Кельвина.
  • Tint — смещение от зеленого или магдента от 0 до 150 с положительными значениями к зеленому направлению и отрицательному направлению в магенду.

CaptureDevice.GetTemperatureAndTintValuesCaptureDevice.GetDeviceWhiteBalanceGainsИспользуйте методы для преобразования между температурой и тоном, хроматистью и RGB-цветными пространствами.

Примечание.

Подпрограммы преобразования более точны, чем ближе значение, которое необходимо преобразовать, — в Планкийский локус.

Поддержка серых карточек

Apple использует термин "Серый мир" для обозначения поддержки серых карт, встроенной в iOS 8. Он позволяет пользователю сосредоточиться на физической серой карточке, которая охватывает по крайней мере 50 % центра кадра и использует это для настройки белого баланса. Цель серой карточки — достичь белого цвета, который появляется нейтральным.

Это можно реализовать в приложении, побудив пользователя разместить физический серый карта перед камерой, отслеживать GrayWorldDeviceWhiteBalanceGains свойство и ждать, пока значения не уладятся.

Затем приложение заблокирует получение белого баланса для SetWhiteBalanceModeLockedWithDeviceWhiteBalanceGains метода, используя значения из GrayWorldDeviceWhiteBalanceGains свойства, чтобы применить изменения.

Устройство записи должно быть заблокировано для настройки перед изменением в белом балансе.

Пример балансировки белого баланса вручную

С помощью кода UIViewController установки общей программы записи AV можно добавить в раскадровку приложения и настроить следующим образом:

UiViewController можно добавить в приложения Storyboard и настроить, как показано здесь для примера баланса вручную.

Представление содержит следующие основные элементы:

  • Будет UIImageView отображаться видеотрансляции.
  • Значение UISegmentedControl , которое изменит режим фокусировки с автоматического на заблокированное.
  • Два UISlider элемента управления, отображающие и обновляющие температуру и тон.
  • Используется UIButton для выборки пробела серой карточки (серый мир) и задания белого баланса с помощью этих значений.

Выполните следующие действия, чтобы подключить контроллер представления для ручного элемента управления "Белый баланс".

  1. Добавьте операторы 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. Добавьте следующие частные переменные:

    #region Private Variables
    private NSError Error;
    private bool Automatic = true;
    #endregion
    
  3. Добавьте следующие вычисляемые свойства:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    public Timer SampleTimer { get; set; }
    #endregion
    
  4. Добавьте следующий частный метод, чтобы задать новый баланс температуры и тон.

    #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. Переопределите ViewDidLoad метод и добавьте следующий код:

    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. Переопределите ViewDidAppear метод и добавьте следующее, чтобы начать запись при загрузке представления:

    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. Сохраните изменения кода и запустите приложение.

  8. При использовании камеры в автоматическом режиме ползунки будут автоматически перемещаться, так как камера настраивает баланс белого цвета:

    Ползунки будут автоматически перемещаться, так как камера настраивает белый баланс

  9. Коснитесь заблокированного сегмента и перетащите ползунки Temp и Tint, чтобы настроить баланс белого цвета вручную:

    Перетащите ползунки Temp и Tint, чтобы настроить баланс белого цвета вручную

  10. Если сегмент заблокирован по-прежнему выбран, поместите физический серый карта перед камерой и нажмите кнопку "Серая карточка", чтобы настроить баланс белого цвета на серый мир:

    Нажмите кнопку

  11. Остановите приложение.

Приведенный выше код показывает, как отслеживать параметры баланса белого цвета, если камера находится в автоматическом режиме или использует ползунки для управления балансом белого цвета, когда он находится в режиме блокировки.

Запечатленное скобок

Запись с квадратными скобками основана на параметрах, представленных выше вручную Камера элементов управления, и позволяет приложению захватить момент времени различными способами.

Просто говоря, скобок захвата является всплеском по-прежнему изображений, сделанных с различными параметрами от рисунка до рисунка.

Как работает захват с скобками

С помощью записи с квадратными скобками в iOS 8 приложение может предустановить ряд элементов управления вручную Камера, выполнить одну команду и вернуть текущую сцену ряд изображений для каждого из предустановок вручную.

Основы записи с квадратными скобками

Опять же, скобок захвата является всплеском по-прежнему изображений, сделанных с различными параметрами от рисунка до рисунка. Доступны следующие типы записей с квадратными скобками:

  • Автоматическая скобка экспозиции — где все изображения имеют разнообразную величину предвзятости.
  • Ручная скобка экспозиции — где все изображения имеют разнообразную скорость затвора (длительность) и объем ISO.
  • Простая скобка всплеска — серия по-прежнему изображений, сделанных в быстром последовательности.

Новые элементы управления захвата с квадратными скобками в iOS 8

Все команды записи с квадратными скобками реализуются в AVCaptureStillImageOutput классе. CaptureStillImageBracketИспользуйте метод, чтобы получить ряд изображений с заданным массивом параметров.

Для обработки параметров реализованы два новых класса:

  • AVCaptureAutoExposureBracketedStillImageSettings — оно имеет одно свойство, ExposureTargetBiasиспользуемое для задания предвзятости для автоматической скобки экспозиции.
  • AVCaptureManualExposureBracketedStillImageSettings — Он имеет два свойства, ExposureDuration и ISOиспользуется для установки скорости затвора и ISO для ручной скобки экспозиции.

Элементы управления "Запись в скобках" и "Не"

Do's

Ниже приведен список действий, которые необходимо сделать при использовании элементов управления "Запись в скобках" в iOS 8.

  • Подготовьте приложение к худшей ситуации захвата путем вызова PrepareToCaptureStillImageBracket метода.
  • Предположим, что образец буферов будет поступать из одного общего пула.
  • Чтобы освободить память, выделенную предыдущим вызовом подготовки, вызовите PrepareToCaptureStillImageBracket еще раз и отправьте его массив одного объекта.

Don'ts

Ниже приведен список вещей, которые не должны выполняться при использовании элементов управления "Запись в скобках" в iOS 8.

  • Не смешивайте типы параметров записи с квадратными скобками в одном захвате.
  • Не запрашивайте больше MaxBracketedCaptureStillImageCount изображений в одном захвате.

Сведения о захвате в квадратных скобках

При работе с записью с квадратными скобками в iOS 8 следует учитывать следующие сведения:

  • Параметры с квадратными скобками временно переопределяют AVCaptureDevice параметры.
  • Параметры стабилизации изображений и флэш-памяти игнорируются.
  • Все изображения должны использовать один и тот же формат вывода (jpeg, png и т. д.)
  • Предварительный просмотр видео может удалять кадры.
  • Запись с квадратными скобками поддерживается на всех устройствах, совместимых с iOS 8.

Учитывая эти сведения, давайте рассмотрим пример использования скобок для захвата в iOS 8.

Пример записи скобок

С помощью кода UIViewController установки общей программы записи AV можно добавить в раскадровку приложения и настроить следующим образом:

UiViewController можно добавить в приложения Storyboard и настроить, как показано в примере захвата квадратных скобок.

Представление содержит следующие основные элементы:

  • Будет UIImageView отображаться видеотрансляции.
  • Три UIImageViews , которые будут отображать результаты захвата.
  • Для UIScrollView размещения видеотрансляции и просмотра результатов.
  • Используется UIButton для захвата с квадратными скобками с некоторыми предварительно заданными параметрами.

Выполните следующие действия, чтобы подключить контроллер представления для записи в квадратных скобках:

  1. Добавьте операторы 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. Добавьте следующие частные переменные:

    #region Private Variables
    private NSError Error;
    private List<UIImageView> Output = new List<UIImageView>();
    private nint OutputIndex = 0;
    #endregion
    
  3. Добавьте следующие вычисляемые свойства:

    #region Computed Properties
    public AppDelegate ThisApp {
        get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
    }
    #endregion
    
  4. Добавьте следующий закрытый метод для создания необходимых представлений выходных изображений:

    #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. Переопределите ViewDidLoad метод и добавьте следующий код:

    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. Переопределите ViewDidAppear метод и добавьте следующий код:

    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. Сохраните изменения кода и запустите приложение.

  8. Кадр сцены и нажмите кнопку "Захватить скобку":

    Кадр сцены и нажмите кнопку

  9. Проводите пальцем вправо влево, чтобы увидеть три изображения, сделанные в скобках:

    Проводите пальцем вправо влево, чтобы увидеть три изображения, сделанные в скобках

  10. Остановите приложение.

Приведенный выше код показано, как настроить и принять функцию автоматического захвата скобок в квадратных скобках в iOS 8.

Итоги

В этой статье мы рассмотрели общие сведения о новых элементах управления Камера вручную, предоставляемых iOS 8, и рассмотрели основы того, что они делают и как они работают. Мы дали примеры ручного фокуса, ручной экспозиции и ручного белого баланса. Наконец, мы дали пример создания скобок с помощью ранее рассмотренных вручную элементов управления Камера