我正在开发一款iOS应用程序,其中一项功能是扫描QR码。为此,我使用了优秀的图书馆ZBar。扫描工作正常,通常很快。但是,当您使用较小的QR码时,扫描需要更长的时间,主要是因为自动对焦需要一些时间来调整。我正在尝试并注意到可以使用以下代码锁定焦点:
AVCaptureDevice *cameraDevice = readerView.device;
if ([cameraDevice lockForConfiguration:nil]) {
[cameraDevice setFocusMode:AVCaptureFocusModeLocked];
[cameraDevice unlockForConfiguration];
}
在成功扫描后使用此代码时,即将进行的扫描非常快。这让我很奇怪,在扫描一个代码之前,我能以某种方式锁定焦点吗?该应用程序将只扫描相当小的QR码,因此永远不需要专注于远处的东西。当然,我可以实现像tap一样专注的东西,但最好是我想避免这个额外的步骤。 有没有办法实现这个目标?或者在处理较小的QR码时是否有其他方法可以加快速度?
//亚历山大
答案 0 :(得分:22)
在iOS7中,现在可以实现!
Apple已将属性autoFocusRangeRestriction添加到AVCaptureDevice类。此属性属于枚举AVCaptureAutoFocusRangeRestriction,它有三个不同的值:
要检查方法是否可用,我们应首先检查属性autoFocusRangeRestrictionSupported是否为true。而且由于它仅在iOS7中支持,我们还应该使用respondsToSelector,因此我们不会在早期的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,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引入ARMv7时,我现在不得不再为ARM64重新编译它。
//亚历山大
答案 1 :(得分:5)
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的方法
答案 2 :(得分:-2)
iOS仅在相机开启时执行对焦 - 此时相机已经打开,为什么还要打扰?你不能给相机一个特定的距离来关注 - 这是它的工作。
用户习惯于相机花时间进行调整,所以请保持原样。但不过很注重细节。
[cameraDevice setFocusMode:AVCaptureFocusModeLocked];
用于在摄影类应用中实现焦点锁定。