iOS 5 – AVCaptureDevice设置对焦点和对焦模式冻结现场摄像头图像

我使用以下方法来设置从iOS 4开始的焦点:

- (void) focusAtPoint:(CGPoint)point { AVCaptureDevice *device = [[self captureInput] device]; NSError *error; if ([device isFocusModeSupported:AVCaptureFocusModeAutoFocus] && [device isFocusPointOfInterestSupported]) { if ([device lockForConfiguration:&error]) { [device setFocusPointOfInterest:point]; [device setFocusMode:AVCaptureFocusModeAutoFocus]; [device unlockForConfiguration]; } else { NSLog(@"Error: %@", error); } } } 

在iOS 4设备上,这个工作没有任何问题。 但在iOS 5上,实时摄像机馈送冻结,几秒钟后完全变黑。 没有exception或错误抛出。

如果我注释掉setFocusPointOfInterest或setFocusMode,则错误不会发生。 所以他们的组合都会导致这种行为。

你给setFocusPointOfInterest:函数的地方是不正确的。 这是它崩溃的原因。

将此方法添加到您的程序中,并使用此函数返回的值

  - (CGPoint)convertToPointOfInterestFromViewCoordinates:(CGPoint)viewCoordinates { CGPoint pointOfInterest = CGPointMake(.5f, .5f); CGSize frameSize = [[self videoPreviewView] frame].size; AVCaptureVideoPreviewLayer *videoPreviewLayer = [self prevLayer]; if ([[self prevLayer] isMirrored]) { viewCoordinates.x = frameSize.width - viewCoordinates.x; } if ( [[videoPreviewLayer videoGravity] isEqualToString:AVLayerVideoGravityResize] ) { pointOfInterest = CGPointMake(viewCoordinates.y / frameSize.height, 1.f - (viewCoordinates.x / frameSize.width)); } else { CGRect cleanAperture; for (AVCaptureInputPort *port in [[[[self captureSession] inputs] lastObject] ports]) { if ([port mediaType] == AVMediaTypeVideo) { cleanAperture = CMVideoFormatDescriptionGetCleanAperture([port formatDescription], YES); CGSize apertureSize = cleanAperture.size; CGPoint point = viewCoordinates; CGFloat apertureRatio = apertureSize.height / apertureSize.width; CGFloat viewRatio = frameSize.width / frameSize.height; CGFloat xc = .5f; CGFloat yc = .5f; if ( [[videoPreviewLayer videoGravity] isEqualToString:AVLayerVideoGravityResizeAspect] ) { if (viewRatio > apertureRatio) { CGFloat y2 = frameSize.height; CGFloat x2 = frameSize.height * apertureRatio; CGFloat x1 = frameSize.width; CGFloat blackBar = (x1 - x2) / 2; if (point.x >= blackBar && point.x <= blackBar + x2) { xc = point.y / y2; yc = 1.f - ((point.x - blackBar) / x2); } } else { CGFloat y2 = frameSize.width / apertureRatio; CGFloat y1 = frameSize.height; CGFloat x2 = frameSize.width; CGFloat blackBar = (y1 - y2) / 2; if (point.y >= blackBar && point.y <= blackBar + y2) { xc = ((point.y - blackBar) / y2); yc = 1.f - (point.x / x2); } } } else if ([[videoPreviewLayer videoGravity] isEqualToString:AVLayerVideoGravityResizeAspectFill]) { if (viewRatio > apertureRatio) { CGFloat y2 = apertureSize.width * (frameSize.width / apertureSize.height); xc = (point.y + ((y2 - frameSize.height) / 2.f)) / y2; yc = (frameSize.width - point.x) / frameSize.width; } else { CGFloat x2 = apertureSize.height * (frameSize.height / apertureSize.width); yc = 1.f - ((point.x + ((x2 - frameSize.width) / 2)) / x2); xc = point.y / frameSize.height; } } pointOfInterest = CGPointMake(xc, yc); break; } } } return pointOfInterest; } 

我想给@Louis的答案一些额外的信息。

根据苹果的文件 (请注意粗体部分):

另外,设备可以支持焦点。 您使用focusPointOfInterestSupportedtesting支持。 如果支持,则使用focusPointOfInterest设置焦点。 您传递了一个CGPoint,其中{0,0}代表图片区域的左上angular,{1,1}代表右侧的Homebutton在横向模式下的右下angular, 即使设备处于纵向模式。

计算FocusPointOfInterest时应该涉及到方向。