【发布时间】:2012-04-20 15:28:33
【问题描述】:
我想在特定情况下捕获图像,例如按下按钮时;但我不想显示任何视频预览屏幕。我想 captureStillImageAsynchronouslyFromConnection 是我需要在这种情况下使用的。目前,如果我显示视频预览,我可以捕获图像。但是,如果我删除代码以显示预览,应用程序会崩溃并显示以下输出:
2012-04-07 11:25:54.898 imCapWOPreview[748:707] *** 终止应用程序 由于未捕获的异常'NSInvalidArgumentException',原因:'*** -[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:] - 已通过非活动/无效连接。 *** 第一次抛出调用堆栈:(0x336ee8bf 0x301e21e5 0x3697c35d 0x34187 0x33648435 0x310949eb 0x310949a7 0x31094985 0x310946f5 0x3109502d 0x3109350f 0x31092f01 0x310794ed 0x31078d2d 0x37db7df3 0x336c2553 0x336c24f5 0x336c1343 0x336444dd 0x336443a5 0x37db6fcd 0x310a7743 0x33887 0x3382c) 终止调用抛出异常(lldb)
这是我的实现:
BIDViewController.h:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface BIDViewController : UIViewController
{
AVCaptureStillImageOutput *stillImageOutput;
}
@property (strong, nonatomic) IBOutlet UIView *videoPreview;
- (IBAction)doCap:(id)sender;
@end
BIDViewController.m 中的相关人员:
#import "BIDViewController.h"
@interface BIDViewController ()
@end
@implementation BIDViewController
@synthesize capturedIm;
@synthesize videoPreview;
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupAVCapture];
}
- (BOOL)setupAVCapture
{
NSError *error = nil;
AVCaptureSession *session = [AVCaptureSession new];
[session setSessionPreset:AVCaptureSessionPresetHigh];
/*
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.videoPreview.bounds;
[self.videoPreview.layer addSublayer:captureVideoPreviewLayer];
*/
// Select a video device, make an input
AVCaptureDevice *backCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error];
if (error)
return NO;
if ([session canAddInput:input])
[session addInput:input];
// Make a still image output
stillImageOutput = [AVCaptureStillImageOutput new];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
if ([session canAddOutput:stillImageOutput])
[session addOutput:stillImageOutput];
[session startRunning];
return YES;
}
- (IBAction)doCap:(id)sender {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillImageOutput.connections)
{
for (AVCaptureInputPort *port in [connection inputPorts])
{
if ([[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *__strong error) {
// Do something with the captured image
}];
}
使用上面的代码,如果调用了doCap,那么就会发生crash。另一方面,如果我在 setupAVCapture 函数中删除以下 cmets
/*
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.videoPreview.bounds;
[self.videoPreview.layer addSublayer:captureVideoPreviewLayer];
*/
然后它就可以正常工作了。
总之,我的问题是,如何在受控实例中捕获图像而不显示预览?
【问题讨论】:
-
最简单的方法是
self.videoPreview.hidden = YES; -
该代码适用于我的 iphone 4S
-
@phix23 隐藏 videoPreview 也对我有用......那么下一个问题是;这种方法有性能损失吗?即是否花费了冗余处理来将视频预览数据发送到隐藏层?
标签: iphone ios avfoundation capture