首页 > 代码库 > 自定义相机(二) -- 拍照

自定义相机(二) -- 拍照

 

 

实现功能:

  相机拍照,把图像保持到系统相册。

 

运行环境:

  1.  XCODE 5.1.1 

  2.  真机(IPHONE5  ,  IOS6.1.4)

 

 

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>       //导入 - "视频流"




@interface MCViewController : UIViewController


@property (strong, nonatomic) AVCaptureSession * captureSession;            //AVCaptureSession实例
@property (strong, nonatomic) AVCaptureDeviceInput * videoInput;            //持有视频输入实例


@property (strong, nonatomic) AVCaptureStillImageOutput * stillImageOutput;  //持有静态图像输出实例


@end

 

 

 

//
//  MCViewController.m
//  MyCamera


#import "MCViewController.h"

@interface MCViewController ()

@end

@implementation MCViewController




#pragma mark - life cycle


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    //开始扑捉会话
    [self.captureSession startRunning];
}




- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    //停止扑捉会话
    [self.captureSession stopRunning];
}




- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //初始化视频流
    [self initAv];
    
    //添加拍照按钮
    [self addCaptureButton];
}





#pragma mark - 初始化视频流

- (void) initAv
{
    //1.1 创建AVCaptureSession
    self.captureSession = [[AVCaptureSession alloc] init];
    //1.2 指定输入设备。这里使用后摄像头。
    AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    //1.3 创建AVCaptureDeviceInput的实例,将所选设备作为扑捉会话的输入。
    //      此外,在将是其添加到回话前请创建好输入,这里需要做个检查。
    NSError * error = nil;
    self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    if (self.videoInput) {
        [self.captureSession addInput:self.videoInput];
    }
    else
    {
        NSLog(@"input error : %@", error);
    }
    
    //2. 创建预览层
    AVCaptureVideoPreviewLayer * previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
    UIView * aView = self.view;
    previewLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [aView.layer addSublayer:previewLayer];
    
    
    //3. 实现拍照
    self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary * stillImageOutputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
    [self.stillImageOutput setOutputSettings:stillImageOutputSettings];
    [self.captureSession addOutput:self.stillImageOutput];
    
}


#pragma mark - 添加按钮 AND 点击按钮事件

- (void)addCaptureButton
{
    CGRect frame = CGRectMake(0, 0, 100, 100);
    UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = frame;
    [btn setTitle:@"拍照" forState:UIControlStateNormal];
    btn.backgroundColor = [UIColor clearColor];
    btn.tag = 1111;
    [btn addTarget:self action:@selector(onClickCaptureButton:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
}



-(IBAction)onClickCaptureButton:(id)sender
{
    [self takePicture];
}




#pragma mark - 保持图像到相册

- (void)saveImageToPhotos:(UIImage*)savedImage
{
    UIImageWriteToSavedPhotosAlbum(savedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}


// 指定回调方法
- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo
{
    NSString * msg = nil ;
    if(error != NULL)
    {
        msg = @"保存图片失败" ;
    }
    else
    {
        msg = @"保存图片成功" ;
    }
    
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"保存图片结果提示"
                                                    message:msg
                                                   delegate:self
                                          cancelButtonTitle:@"确定"
                                          otherButtonTitles:nil];
    [alert show];
}





#pragma mark - 拍照函数


//拍照
- (void) takePicture
{
    //1.
    AVCaptureConnection * stillImageConnection = [self.stillImageOutput.connections objectAtIndex:0];
    
    if ([stillImageConnection isVideoOrientationSupported]) {
        [stillImageConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
    }
    
    //2.
    [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        
        
        if (imageDataSampleBuffer != NULL)
        {
            //图像数据类型转换
            NSData * imageData =http://www.mamicode.com/ [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            UIImage * image = [[UIImage alloc] initWithData:imageData];
            
            //保存图像
            [self saveImageToPhotos:image];
            
        }
        else
        {
            NSLog(@"Error capturing still image %@", error);
        }
    }];
    
}


@end