iOS-拍照和调用本地图片

#import #import "YXKPhotoController.h" #import "AVPlayerDemoPlaybackView.h" #import "VideoCore.h" #import "YXKPublishController.h"@interface YXKPhotoController () { __weak IBOutlet UIView *photoView; __weak IBOutlet UIButton *turnCameraButton; __weak IBOutlet UIButton *lightningButton; __weak IBOutlet UIButton *cancleButton; __weak IBOutlet UIButton *photoButton; __weak IBOutlet UIButton *addPhotoButton; AVCaptureSession *AVSession; }@property (nonatomic, strong) AVCaptureSession *session; @property (nonatomic) BOOL isFlashLight; @property (nonatomic, strong) AVCaptureDeviceInput *videoInput; @property (nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput; @property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; @end@implementation YXKPhotoController- (void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.tabBarController.tabBar.hidden = NO; }- (void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.tabBarController.tabBar.hidden = YES; }#pragma mark -- 加载预览图层 - (void) setUpCameraLayer { if (self.previewLayer == nil) { self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; UIView * view = photoView; CALayer * viewLayer = [view layer]; [viewLayer setMasksToBounds:YES]; CGRect bounds = [view bounds]; [self.previewLayer setFrame:bounds]; [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; [viewLayer insertSublayer:self.previewLayer below:[[viewLayer sublayers] objectAtIndex:0]]; } }- (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if(self.session) { [self.session startRunning]; } }- (void)viewDidLoad { [super viewDidLoad]; [self checkDeviceAuthorizationStatus]; self.isFlashLight = NO; //这个方法的执行我放在init方法里了 self.session = [[AVCaptureSession alloc] init]; self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backCamera] error:nil]; //[self fronCamera]方法会返回一个AVCaptureDevice对象,因为我初始化时是采用前摄像头,所以这么写,具体的实现方法后面会介绍 self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil]; //这是输出流的设置参数AVVideoCodecJPEG参数表示以JPEG的图片格式输出图片 [self.stillImageOutput setOutputSettings:outputSettings]; if ([self.session canAddInput:self.videoInput]) { [self.session addInput:self.videoInput]; } if ([self.session canAddOutput:self.stillImageOutput]) { [self.session addOutput:self.stillImageOutput]; }}#pragma mark -- 打开闪光灯 - (IBAction)turnButtonClick:(id)sender { self.isFlashLight = !self.isFlashLight; if(self.isFlashLight) { [lightningButton setImage:[UIImage imageNamed:@"picker_flash_sel.png"] forState:UIControlStateNormal]; } else { [lightningButton setImage:[UIImage imageNamed:@"picker_flash.png"] forState:UIControlStateNormal]; [self closeFlashLight]; } }-(void)openFlashLight { AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if (device.torchMode == AVCaptureTorchModeOff) { //Create an AV session AVCaptureSession * session = [[AVCaptureSession alloc]init]; // Create device input and add to current session AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; [session addInput:input]; // Create video output and add to current session AVCaptureVideoDataOutput * output = [[AVCaptureVideoDataOutput alloc]init]; [session addOutput:output]; // Start session configuration [session beginConfiguration]; [device lockForConfiguration:nil]; // Set torch to on [device setTorchMode:AVCaptureTorchModeOn]; [device unlockForConfiguration]; [session commitConfiguration]; // Start the session [session startRunning]; // Keep the session around [self setSession:self.session]; } }- (void) closeFlashLight {}#pragma mark -- 反转摄像头 - (IBAction)turnCameraButtonClick:(id)sender { [self toggleCamera]; }#pragma mark --翻转摄像头 - (void)toggleCamera { // p判断设备上有几个摄像头 NSUInteger cameraCount = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count]; if (cameraCount > 1) { NSError *error; AVCaptureDeviceInput *newVideoInput; // 获取当前的摄像头是前置还是后置 AVCaptureDevicePosition position = [[_videoInput device] position]; if (position == AVCaptureDevicePositionBack) newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontCamera] error:&error]; else if (position == AVCaptureDevicePositionFront) newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backCamera] error:&error]; else return; if (newVideoInput != nil) { // 改变回话的配置前,一定要开启配置,配置完成后提交配置改变 [self.session beginConfiguration]; [self.session removeInput:self.videoInput]; if ([self.session canAddInput:newVideoInput]) { [self.session addInput:newVideoInput]; [self setVideoInput:newVideoInput]; } else { [self.session addInput:self.videoInput]; } // 提交新的配置信息 [self.session commitConfiguration]; } else if (error) { NSLog(@"toggle carema failed, error = %@", error); } } }- (IBAction)cancleButtonClick:(id)sender { self.tabBarController.selectedIndex =0; }#pragma mark -- 调用摄像头拍照,并且跳转到发布界面 - (IBAction)photoButtonClick:(id)sender { [self readImageFromCamera]; }#pragma mark -- 从摄像头获取照片 - (void) readImageFromCamera { AVCaptureConnection * videoConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; if (!videoConnection) { NSLog(@"take photo failed!"); return; }[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { if (imageDataSampleBuffer == NULL) { return; }NSData * imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; UIImage * image = [UIImage imageWithData:imageData]; NSLog(@"image size = %@",NSStringFromCGSize(image.size)); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.03 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if(self.session) { if(self.isFlashLight) { [self openFlashLight]; } [self.session stopRunning]; } YXKPublishController *publish = [[YXKPublishController alloc] init]; publish.image = image; [self.navigationController pushViewController:publish animated:YES]; }); }]; }#pragma mark -- 访问本地照片库 - (IBAction)addPhotoButtonClick:(id)sender { [self readImageFromAlbum]; }#pragma mark -- 从本地读取相册 - (void) readImageFromAlbum { UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; // 设置类型, 表示仅仅从相册中获取照片 imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; imagePicker.delegate = self; // 设置照片是否允许用户编辑 imagePicker.allowsEditing = NO; [self presentViewController:imagePicker animated:YES completion:nil]; }#pragma mark -- 图片完成处理后提交,代理方法UIPickerControllerDelegate - (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo { YXKPublishController *publish = [[YXKPublishController alloc] init]; publish.image = image; [self.navigationController pushViewController:publish animated:YES]; }#pragma mark -- 这是获取前后摄像头对象的方法 - (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position { NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *device in devices) { if ([device position] == position) { return device; } } return nil; }- (AVCaptureDevice *)frontCamera { return [self cameraWithPosition:AVCaptureDevicePositionFront]; }- (AVCaptureDevice *)backCamera { return [self cameraWithPosition:AVCaptureDevicePositionBack]; }#pragma mark -- 是否拥有使用摄像头的权限 - (void)checkDeviceAuthorizationStatus { [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if (granted) { dispatch_async(dispatch_get_main_queue(), ^{ [self setUpCameraLayer]; }); } else { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertController * alert = [UIAlertController alertControllerWithTitle:nil message:@"No permission to use Camera, please change privacy settings" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { [self cancleButtonClick:nil]; }]]; [self presentViewController:alert animated:YES completion:nil]; }); } }]; }- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }@end

    推荐阅读