iOS10かつObjective Cで、AVCapturePhotoOutputが見つからなかったのでやってみた報告です。
カメラで撮影してUIImageViewに表示する(UIImagePickerContrllerを使って)の続き。AVCapturePhotoOutputを使って、カメラ撮影を試みます。
まず、Info.plistにNSCameraUsageDescriptionとNSPhotoLibraryUsageDescriptionを追加します。
AVCaptureStillImageOutputを用いたサンプルが多く見つかるものの、iOS10で廃止されたため、AVCapturePhotoOutputクラスを用います。
まずは、AVFoundationライブラリをプロジェクトの設定で追加し、 #import "AVFoundation/AVFoundation.h"
します。
残りはこれだ!どーん。
https://github.com/sahara-ooga/objc-basic/blob/master/2-5-3/ にあります。
#import "CameraViewController.h"
@interface CameraViewController ()
//リアルタイムでプレビューする画面を想定
@property (weak, nonatomic) IBOutlet UIImageView *videoPreviewView;
//撮影した画像を表示するビュー
@property (weak, nonatomic) IBOutlet UIImageView *photoView;
//AV Foundation
@property (nonatomic) AVCaptureSession *captureSesssion;
@property AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (nonatomic) AVCapturePhotoOutput *stillImageOutput;
@end
@implementation CameraViewController
/**
ビデオカメラからの映像をimageViewに表示する設定を行う。
*/
- (void)viewDidLoad {
[super viewDidLoad];
self.captureSesssion = [[AVCaptureSession alloc] init];
self.captureSesssion.sessionPreset = AVCaptureSessionPreset1920x1080;
self.stillImageOutput = [[AVCapturePhotoOutput alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = [[NSError alloc] init];
/**
Swiftでは、AVCaptureDeviceInputの初期化はthrowsになっており、do catch節に入っているので、こちらも合わせた
*/
@try{
AVCaptureDeviceInput* input = [[AVCaptureDeviceInput alloc] initWithDevice:device
error:&error];
if ([self.captureSesssion canAddInput:input]) {
[self.captureSesssion addInput:input];
if ([self.captureSesssion canAddOutput:self.stillImageOutput]) {
[self.captureSesssion addOutput:self.stillImageOutput];
[self.captureSesssion startRunning];
AVCaptureVideoPreviewLayer* captureVideoLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSesssion];
captureVideoLayer.frame = self.videoPreviewView.bounds;
captureVideoLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.videoPreviewView.layer addSublayer:captureVideoLayer];
}
}
}
@catch (NSException *ex){
NSLog(@"%@",error);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//撮影ボタンを押した際に呼ばれるメソッド。
- (IBAction)takePhoto:(UIButton *)sender {
AVCapturePhotoSettings* settings = [[AVCapturePhotoSettings alloc] init];
settings.flashMode = AVCaptureFlashModeAuto;
[self.stillImageOutput capturePhotoWithSettings:settings
delegate:self];
}
#pragma mark AVCapturePhotoCaptureDelegate
-(void)captureOutput:(AVCapturePhotoOutput *)captureOutput
didFinishProcessingPhotoSampleBuffer:(nullable CMSampleBufferRef)photoSampleBuffer
previewPhotoSampleBuffer:(nullable CMSampleBufferRef)previewPhotoSampleBuffer
resolvedSettings:(nonnull AVCaptureResolvedPhotoSettings *)resolvedSettings
bracketSettings:(nullable AVCaptureBracketedStillImageSettings *)bracketSettings
error:(nullable NSError *)error
{
NSData* photoData = [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:photoSampleBuffer
previewPhotoSampleBuffer:previewPhotoSampleBuffer];
UIImage* resultImage = [[UIImage alloc] initWithData:photoData];
self.photoView.image = resultImage;
UIImageWriteToSavedPhotosAlbum(resultImage, nil, nil, nil);
}
@end
Xcode v8.3.1 (8E1000a),macOS Sierra 10.12.4, iPhone 5S, iOS 10.2,もちろんObjective C