【问题标题】:Set an initial focal distance on iOS在 iOS 上设置初始焦距
【发布时间】:2013-03-24 19:23:51
【问题描述】:

我正在开发一个 iOS 应用程序,其中一项功能是扫描 QR 码。为此,我使用了出色的库 ZBar。扫描工作正常,通常非常快。但是,当您使用较小的 QR 码时,扫描时间会更长,这主要是因为自动对焦需要一些时间来调整。我在试验并注意到可以使用以下代码锁定焦点:

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

在成功扫描后使用此代码时,即将进行的扫描非常快。这让我想知道,我可以在扫描一个代码之前以某种方式锁定焦点吗?该应用程序只会扫描相当小的二维码,因此永远不需要关注远处的东西。当然,我可以实现诸如点击聚焦之类的东西,但最好我想避免那个额外的步骤。 有没有办法做到这一点?或者在处理较小的 QR 码时是否有其他加快处理速度的方法?

// 亚历山大

【问题讨论】:

  • @amigable-clark-kant,是的,这似乎是基本相同的问题,只是他想尽可能远地锁定焦点。看来我当前的解决方案(第一次成功扫描后锁定焦点)或“点击对焦”是目前最好的解决方案。

标签: ios camera focus qr-code


【解决方案1】:

在 iOS7 中,这现在是可能的!

Apple 已将属性 autoFocusRangeRestriction 添加到 AVCaptureDevice 类。此属性属于枚举 AVCaptureAutoFocusRangeRestriction,它具有三个不同的值:

  1. AVCaptureAutoFocusRangeRestrictionNone - 默认,无限制
  2. AVCaptureAutoFocusRangeRestrictionNear - 重要的拍摄对象靠近相机
  3. AVCaptureAutoFocusRangeRestrictionFar - 重要的主体远离相机

要检查方法是否可用,我们应该首先检查属性 autoFocusRangeRestrictionSupported 是否为真。而且由于它仅在 iOS7 和更高版本中受支持,我们还应该使用 respondsToSelector,这样我们就不会在早期的 iO​​S 版本中遇到异常。
所以生成的代码应该是这样的:

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

结果是一个非常活泼的扫描仪。 我还使用 iOS7 中引入的 API 构建了一个自定义扫描仪,而不是使用 ZBar。主要是因为 ZBar-libs 已经过时了,而且当 iPhone 5 引入 ARMv7s 时,我现在不得不为 ARM64 重新编译它。

// 亚历山大

【讨论】:

  • 现在如何强制照片应用密切对焦? :-) 点击屏幕总是想专注于背景。我已经学会了为微距拍摄锁定焦点,但我希望我可以使用焦点限制器。另外,API中是否有可以返回焦距的东西?这在创建应用程序以将位置信息添加到图片时可能很有用,您想要的主题位置,而不是设备位置。
【解决方案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's 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);

编辑:这是 AVCaptureDevice 的一种方法

【讨论】:

  • 是的,这几乎就像他们真的在听 :) 我使用这种方法来锁定焦点。但大多数时候,它带来的问题多于解决的问题。您必须将 QR 码/条形码保持在非常特定的距离,当您拥有不同大小的代码时,这可能会导致问题。但是,我认为我找到了一个很好的替代方法来完全锁定焦点。当用户按下扫描按钮时,我将焦点锁定在近距离,完成后我将相机切换回自动对焦。这样我们可以使用自动对焦,但相机会得到一个很好的起始位置。
猜你喜欢
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 2021-01-04
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
相关资源
最近更新 更多