在没有相机界面的情况下,我找不到简单的拍照方式。 我只需要从相机中取出照片并将其保存到文件中。
答案 0 :(得分:6)
我用这段代码用正面相机拍照。并非所有代码都是我的,但我没有找到原始来源的链接。此代码还会产生快门声。图像质量不是很好(很暗),所以代码需要调整一两次。
-(void) takePhoto
{
AVCaptureDevice *frontalCamera;
NSArray *allCameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for ( int i = 0; i < allCameras.count; i++ )
{
AVCaptureDevice *camera = [allCameras objectAtIndex:i];
if ( camera.position == AVCaptureDevicePositionFront )
{
frontalCamera = camera;
}
}
if ( frontalCamera != nil )
{
photoSession = [[AVCaptureSession alloc] init];
NSError *error;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:frontalCamera error:&error];
if ( !error && [photoSession canAddInput:input] )
{
[photoSession addInput:input];
AVCaptureStillImageOutput *output = [[AVCaptureStillImageOutput alloc] init];
[output setOutputSettings:
[[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]];
if ( [photoSession canAddOutput:output] )
{
[photoSession addOutput:output];
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in output.connections)
{
for (AVCaptureInputPort *port in [connection inputPorts])
{
if ([[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
if ( videoConnection )
{
[photoSession startRunning];
[output captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer != NULL)
{
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *photo = [[UIImage alloc] initWithData:imageData];
[self processImage:photo]; //this is a custom method
}
}];
}
}
}
}
}
photoSession
是持有AVCaptureSession *
方法的班级的takePhoto
ivar。
编辑(调整):如果您将if ( videoConnection )
块更改为以下代码,则会增加1秒延迟并获得良好的图像。
if ( videoConnection )
{
[photoSession startRunning];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[output captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRefimageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer != NULL)
{
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *photo = [[UIImage alloc] initWithData:imageData];
[self processImage:photo];
}
}];
});
}
如果您的应用程序无法接受滞后,您可以将代码拆分为两部分,然后在photoSession
(或类似的地方)启动viewDidAppear
,并在需要时立即拍摄快照 - 通常在某些部分之后用户互动。
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.25 * NSEC_PER_SEC);
也会产生良好的结果 - 所以不需要整整一秒。
请注意,此代码用于拍摄带有正面相机的照片 - 如果您需要使用背部相机,我相信您会知道如何修补它。