在 iOS 6 SDK(iOS 5 SDK 以上)中捕捉摄影机的静态拍摄画面,制作类似「录像同时拍照的效果」可以透果很多方式,像是透过
UIImagePickerController 的方式,呼叫 iOS SDK 所提供的 API 来捕捉画面,或是透过 AVFoundation 的 方式,建立影像的 AVCaptureSession,并且设定对应的 Input 与 Output。而本篇文章所采用的方法属于后者,我们使用 AVCaptureStillImageOutput(iOS 10 SDK 以后使用AVCapturePhotoOutput 取代
) 来当做 AVCaptureSession 的 Output 端,输出静态影像。
设置输出
注意:当前仅支持 AVVideoCodecKey 和 kCVPixelBufferPixelFormatTypeKey 使用 -availableImageDataCVPixelFormatTypes 和 -availableImageDataCodecTypes 获取支持的codec keys 和 pixel formats
@property(nonatomic, copy) NSDictionary<NSString *, id> *outputSettings;
实例:
//协调输出流
AVCaptureStillImageOutput *myStillImageOutput = [[AVCaptureStillImageOutput alloc] init];
self.myStillImageOutput = myStillImageOutput;
NSDictionary *myOutputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
[myStillImageOutput setOutputSettings:myOutputSettings];
[_cameraPreviewSession addOutput:myStillImageOutput];
获取支持的图片编码CodecKey
@property(nonatomic, readonly) NSArray<AVVideoCodecType> *availableImageDataCodecTypes;
实例:
NSArray *codeTypes = myStillImageOutput.availableImageDataCodecTypes;
Printing description of codeTypes:
<__NSSingleObjectArrayI 0x1c0006790>(
jpeg
)
获取支持的像素
@property(nonatomic, readonly) NSArray<NSNumber *> *availableImageDataCVPixelFormatTypes;
实例
NSArray *formatTypes = myStillImageOutput.availableImageDataCVPixelFormatTypes;
Printing description of formatTypes:
<__NSArrayI 0x1c0242fd0>(
875704422,
875704438,
1111970369
)
获取静态图片
//是否正在获取静态图
@property(readonly, getter=isCapturingStillImage) BOOL capturingStillImage NS_AVAILABLE(10_8, 5_0);
//注意有可能不是在主线程
- (void)captureStillImageAsynchronouslyFromConnection:(AVCaptureConnection *)connection completionHandler:(void (^)(CMSampleBufferRef _Nullable imageDataSampleBuffer, NSError * _Nullable error))handler;
//从Buffer获取图片的Data
+ (nullable NSData *)jpegStillImageNSDataRepresentation:(CMSampleBufferRef)jpegSampleBuffer;
实例:
-(void)buttonClick{
AVCaptureConnection *myVideoConnection = nil;
//从 AVCaptureStillImageOutput 中取得正确类型的 AVCaptureConnection
for (AVCaptureConnection *connection in self.myStillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
myVideoConnection = connection;
break;
}
}
}
//撷取影像(包含拍照音效)
[self.myStillImageOutput captureStillImageAsynchronouslyFromConnection:myVideoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
//完成撷取时的处理程序(Block)
if (imageDataSampleBuffer) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
//取得的静态影像
UIImage *myImage = [[UIImage alloc] initWithData:imageData];
self.imgView.image = myImage;
//取得影像数据(需要ImageIO.framework 与 CoreMedia.framework)
CFDictionaryRef myAttachments = CMGetAttachment(imageDataSampleBuffer, kCGImagePropertyExifDictionary, NULL);
NSLog(@"影像属性: %@", myAttachments);
}
}];
}
光学图像防抖动功能
//是否支持光学防抖动功能
@property(nonatomic, readonly, getter=isStillImageStabilizationSupported) BOOL stillImageStabilizationSupported NS_AVAILABLE_IOS(7_0);
//光学防抖动是否开启
@property(nonatomic) BOOL automaticallyEnablesStillImageStabilizationWhenAvailable NS_AVAILABLE_IOS(7_0);
//光学防抖是否在执行
@property(nonatomic, readonly, getter=isStillImageStabilizationActive) BOOL stillImageStabilizationActive NS_AVAILABLE_IOS(7_0);
iPhone 6 Plus(只限6 Plus)的后置摄像头支持光学图像防抖动功能。默认配置中,该功能会在低光线情况下,在你使用8百万像素设备格式的AVCaptureStillImageOutput拍照时激活或者预先调整AVCaptureSessionPresetPhoto时激活。 在iOS7中,AV Foundation 使用了相同的属性AVCaptureStillImageOutput automaticallyEnablesStillImageStabilizationWhenAvailable。这个属性在所支持的平台上(iPhone 5s、iPhone 6以及iPhone 6 Plus)默认为YES。在iPhone 5s 和iPhone 6 上,数字图像防抖动技术可减少低光线图片的模糊强度。在iPhone6 Plus上,数字和光学图像防抖动技术的结合可以在光线度更低的情况下达到更好的效果。
网友评论