Подтвердить что ты не робот

Установите начальное фокусное расстояние на iOS

Я работаю над iOS-приложением, где одна из функций сканирует QR-коды. Для этого я использую отличную библиотеку ZBar. Сканирование работает отлично и, как правило, очень быстро. Однако, когда вы используете меньшие QR-коды, для сканирования требуется немного больше времени, в основном из-за того, что для автофокусировки требуется некоторое время для настройки. Я экспериментировал и заметил, что фокус можно заблокировать, используя следующий код:

AVCaptureDevice *cameraDevice = readerView.device;
if ([cameraDevice lockForConfiguration:nil]) {
     [cameraDevice setFocusMode:AVCaptureFocusModeLocked];
     [cameraDevice unlockForConfiguration];
}

Когда этот код используется после успешного сканирования, предстоящие проверки действительно быстрые. Это заставило меня задуматься, можно ли как-то заблокировать фокус, даже если сканировать один код? Приложение будет сканировать только небольшие QR-коды, поэтому никогда не будет необходимости фокусироваться на чем-то далеко. Конечно, я мог бы реализовать что-то вроде tap для фокусировки, но, желательно, я бы хотел избежать этого дополнительного шага. Есть ли способ достичь этого? Или, может быть, есть еще один способ ускорить работу с меньшими QR-кодами?

//Александр

4b9b3361

Ответ 1

В iOS7 теперь это возможно!

Apple добавила свойство autoFocusRangeRestriction в класс AVCaptureDevice. Это свойство имеет перечисление AVCaptureAutoFocusRangeRestriction, которое имеет три разных значения:

  • AVCaptureAutoFocusRangeRestrictionNone - По умолчанию, никаких ограничений
  • AVCaptureAutoFocusRangeRestrictionNear - объект, который имеет значение, близок к камере
  • AVCaptureAutoFocusRangeRestrictionFar - тема, которая имеет значение, далека от камеры.

Чтобы проверить, доступен ли метод, мы должны сначала проверить, истинно ли свойство autoFocusRangeRestrictionSupported. И поскольку он поддерживается только в iOS7, мы также должны использовать responsesToSelector, чтобы мы не получали исключение в более ранних версиях iOS.
Таким образом, полученный код должен выглядеть примерно так:

AVCaptureDevice *cameraDevice = zbarReaderView.device;
if ([cameraDevice respondsToSelector:@selector(isAutoFocusRangeRestrictionSupported)] && cameraDevice.autoFocusRangeRestrictionSupported) {
    // If we are on an iOS version that supports AutoFocusRangeRestriction and the device supports it
    // Set the focus range to "near"
    if ([cameraDevice lockForConfiguration:nil]) {
        cameraDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;
        [cameraDevice unlockForConfiguration];
    }
}

Это несколько ускоряет сканирование небольших QR-кодов в соответствии с моими начальными испытаниями:)

Обновление - iOS8

С iOS8 Apple предоставила нам множество новых API-интерфейсов для камеры. Один из этих новых методов:

- (void)setFocusModeLockedWithLensPosition:(float)lensPosition completionHandler:(void (^)(CMTime syncTime))handler

Этот метод блокирует фокус, перемещая объектив в положение между 0.0 и 1.0. Я играл с помощью метода, фиксируя объектив при близких значениях. Однако, в общем, это вызвало больше проблем, чем это решило. Вы должны были хранить QR-коды/штрих-коды на очень определенном расстоянии, что может вызвать проблемы, когда у вас были коды разного размера.
Но. Я думаю, что нашел довольно хорошую альтернативу фокусу фокуса. Когда пользователь нажимает кнопку сканирования, я фиксирую объектив на близком расстоянии, и когда он закончен, я переключу камеру обратно на автофокус. Это дает нам преимущества сохранения автоматической фокусировки, но заставляет камеру начинать с близкого расстояния, где QR-код/​​штрих-код, вероятно, будет найден. Это в сочетании с:

cameraDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;

и

cameraDevice.focusPointOfInterest = CGPointMake(0.5,0.5);

Результаты в довольно быстрый сканер. Я также создал собственный сканер с API, представленным в iOS7, вместо использования ZBar. В основном потому, что ZBar-libs довольно устарели, и когда iPhone 5 представил ARMv7, мне теперь пришлось снова перекомпилировать его для ARM64.

//Александр

Ответ 2

iOS 8 недавно добавила эту конфигурацию! Это похоже на то, что они читают переполнение стека

    /*!
 @method setFocusModeLockedWithLensPosition:completionHandler:
 @abstract
    Sets focusMode to AVCaptureFocusModeLocked and locks lensPosition at an explicit value.

 @param lensPosition
    The lens position, as described in the documentation for the lensPosition property. A value of AVCaptureLensPositionCurrent can be used
    to indicate that the caller does not wish to specify a value for lensPosition.
 @param handler
    A block to be called when lensPosition has been set to the value specified and focusMode is set to AVCaptureFocusModeLocked. If
    setFocusModeLockedWithLensPosition:completionHandler: is called multiple times, the completion handlers will be called in FIFO order. 
    The block receives a timestamp which matches that of the first buffer to which all settings have been applied. Note that the timestamp 
    is synchronized to the device clock, and thus must be converted to the master clock prior to comparison with the timestamps of buffers 
    delivered via an AVCaptureVideoDataOutput. The client may pass nil for the handler parameter if knowledge of the operation completion 
    is not required.

 @discussion
    This is the only way of setting lensPosition.
    This method throws an NSRangeException if lensPosition is set to an unsupported level.
    This method throws an NSGenericException if called without first obtaining exclusive access to the receiver using lockForConfiguration:.
*/
- (void)setFocusModeLockedWithLensPosition:(float)lensPosition completionHandler:(void (^)(CMTime syncTime))handler NS_AVAILABLE_IOS(8_0);

EDIT: это метод AVCaptureDevice

Ответ 3

Нет, вы не можете.

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

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

[cameraDevice setFocusMode:AVCaptureFocusModeLocked]; предназначен для реализации блокировки фокуса в приложении типа фотографии.