ios 相机 自定义 相片的截取

前段时间公司需要做一个身份识别的功能,而系统相机无法满足要求,so自己自定义了。

上代码:

.h文件

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController

@property (nonatomic, strong) AVCaptureSession* session;
/**
 *  输入设备
 */
@property (nonatomic, strong) AVCaptureDeviceInput* videoInput;
/**
 *  照片输出流
 */
@property (nonatomic, strong) AVCaptureStillImageOutput* stillImageOutput;
/**
 *  预览图层
 */
@property (nonatomic, strong) AVCaptureVideoPreviewLayer* previewLayer;

/**
 *  最后的缩放比例
 */
@property(nonatomic,assign)CGFloat effectiveScale;
@property (nonatomic, strong) UIView *backView;

.m文件

在这个文件你需要什么样的相机都可以在这里面设置,需要放大放小,闪光各种功能都在此处可以设置。

@interface ViewController ()

@end

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated{
    
    [super viewWillAppear:YES];
    
    if (self.session) {
        
        [self.session startRunning];
    }
}


- (void)viewDidDisappear:(BOOL)animated{
    
    [super viewDidDisappear:YES];
    
    if (self.session) {
        
        [self.session stopRunning];
    }
}

- (void)viewDidLoad {
    self.view.backgroundColor = [UIColor blackColor];
    
    self.backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,SelfWidth, SelfHeight - 120)];
    [self.view addSubview:self.backView];
    
    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(SelfWidth/2 - 30, SelfHeight - 120 + 30, 60, 60)];
    view.backgroundColor = [UIColor whiteColor];
    view.layer.cornerRadius = 30;
    [view.layer masksToBounds];
    [self.view addSubview:view];
    
    //自己定义一个和原生的相机一样的按钮
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(SelfWidth/2 - 25, SelfHeight - 120 + 35, 50, 50);
    button.backgroundColor = [UIColor whiteColor];
    button.layer.cornerRadius = 25;
    button.layer.borderWidth = 2;
    button.layer.borderColor = [UIColor blackColor].CGColor;
    [button.layer masksToBounds];
    [button addTarget:self action:@selector(buttondown) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
   //在相机中加个框
    CALayer *Mylayer=[CALayer layer];
    Mylayer.bounds=CGRectMake(10, (SelfHeight - (SelfWidth - 20)/1.6)/2, SelfWidth - 20, (SelfWidth - 20)/1.6);
    Mylayer.position=CGPointMake(SelfWidth/2, (SelfHeight - 120)/2);
    Mylayer.masksToBounds=YES;
    Mylayer.borderWidth=1;
    Mylayer.borderColor=[UIColor whiteColor].CGColor;
    [self.view.layer addSublayer:Mylayer];
    
    
    UIButton *Lbtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    Lbtn.frame = CGRectMake(20, SelfHeight - 80 , 40, 40);
    [Lbtn setTitle:@"取消" forState:UIControlStateNormal];
    Lbtn.titleLabel.font = [UIFont  systemFontOfSize:15];
    [Lbtn setTintColor:[UIColor whiteColor]];
    [Lbtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:Lbtn];
    
    
    [self initAVCaptureSession]; //设置相机属性
    self.effectiveScale = 1.0f;
}

//设置相机属性
- (void)initAVCaptureSession{
    
    self.session = [[AVCaptureSession alloc] init];
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
    
    NSError *error;
    
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    //更改这个设置的时候必须先锁定设备,修改完后再解锁,否则崩溃
    [device lockForConfiguration:nil];
    //设置闪光灯为自动
    [device setFlashMode:AVCaptureFlashModeAuto];
    [device unlockForConfiguration];
    
    self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error];
    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
    if (error) {
        NSLog(@"%@",error);
    }
    self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    //输出设置。AVVideoCodecJPEG   输出jpeg格式图片
    NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
    [self.stillImageOutput setOutputSettings:outputSettings];
    
    if ([self.session canAddInput:self.videoInput]) {
        [self.session addInput:self.videoInput];
    }
    if ([self.session canAddOutput:captureOutput]) {
        [self.session addOutput:captureOutput];
    }
    if ([self.session canAddOutput:self.stillImageOutput]) {
        [self.session addOutput:self.stillImageOutput];
    }
    
    //初始化预览图层
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    NSLog(@"%f",SelfWidth);
    self.previewLayer.frame = CGRectMake(0, 0,SelfWidth, SelfHeight - 120);
    self.backView.layer.masksToBounds = YES;
    [self.backView.layer addSublayer:self.previewLayer];
}
- (AVCaptureVideoOrientation)avOrientationForDeviceOrientation:(UIDeviceOrientation)deviceOrientation
{
    AVCaptureVideoOrientation result = (AVCaptureVideoOrientation)deviceOrientation;
    if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
        result = AVCaptureVideoOrientationLandscapeRight;
    else if ( deviceOrientation == UIDeviceOrientationLandscapeRight )
        result = AVCaptureVideoOrientationLandscapeLeft;
    return result;
}

//照相按钮点击事件
-(void)buttondown{
    NSLog(@"takephotoClick...");
    AVCaptureConnection *stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
    UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];
    AVCaptureVideoOrientation avcaptureOrientation = [self avOrientationForDeviceOrientation:curDeviceOrientation];
    [stillImageConnection setVideoOrientation:avcaptureOrientation];
    [stillImageConnection setVideoScaleAndCropFactor:self.effectiveScale];
    
    [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        
        NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
        
        [self makeImageView:jpegData];
        NSLog(@"jpegDatajpegData == %ld",(unsigned long)[jpegData length]/1024);
        
    }];
}


//拍照之后调到相片详情页面
-(void)makeImageView:(NSData*)data{

    imageDetailViewController*imageView = [[imageDetailViewController alloc] init];
    imageView.data = data;
    
    [self presentViewController:imageView animated:NO completion:nil];
    
}
//返回
-(void)back{
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

再进入详情页面进行照片的裁剪并显示

#import <UIKit/UIKit.h>

@interface imageDetailViewController : UIViewController

@property(nonatomic,strong)NSData *data;
@end
#import "imageDetailViewController.h"

@interface imageDetailViewController ()
{
    UIImage *imageIm;

}
@end

@implementation imageDetailViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blackColor];
    UIImageView *imageView =[[UIImageView alloc] initWithFrame:CGRectMake(0, -64, SelfWidth, SelfHeight)];
    imageView.image = [UIImage imageWithData:_data];
    [self.view addSubview:imageView];
   imageIm =[UIImage imageWithData:_data];
    CGSize originalsize = [ imageView.image size];
    
     NSLog(@"改变前图片的宽度为%f,图片的高度为%f",originalsize.width,originalsize.height);
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(15, SelfHeight - 50, 40, 40);
    [button setTitle:@"重拍" forState:UIControlStateNormal];
    [button setTintColor:[UIColor whiteColor]];
    [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    CALayer *Mylayer=[CALayer layer];
    Mylayer.bounds=CGRectMake(10, (SelfHeight - (SelfWidth - 20)/1.6)/2, SelfWidth - 20, (SelfWidth - 20)/1.6);
    Mylayer.position=CGPointMake(SelfWidth/2, (SelfHeight - 120)/2);
    Mylayer.masksToBounds=YES;
    Mylayer.borderWidth=1;
    Mylayer.borderColor=[UIColor whiteColor].CGColor;
    [self.view.layer addSublayer:Mylayer];
    
    
    
    
    UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    rightButton.frame = CGRectMake(SelfWidth - 90, SelfHeight - 50, 80, 40);
    [rightButton setTitle:@"使用照片" forState:UIControlStateNormal];
    [rightButton setTintColor:[UIColor whiteColor]];
    [rightButton addTarget:self action:@selector(rightButton) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:rightButton];

    // Do any additional setup after loading the view.
}

-(void)rightButton{
   
    
    //截取照片,截取到自定义框内的照片
    imageIm = [self image:imageIm scaleToSize:CGSizeMake(SelfWidth, SelfHeight)];
    //应为在展开相片时放大的两倍,截取时也要放大两倍
    imageIm = [self imageFromImage:imageIm inRect:CGRectMake(10*2, (SelfHeight - (SelfWidth - 20) /1.6)/2*2, (SelfWidth - 20)*2 , (SelfWidth - 20)/1.6*2)];
    
    //将图片存储到相册
     UIImageWriteToSavedPhotosAlbum(imageIm, self, nil, nil);
    
   //截取之后将图片显示在照相时页面,和拍摄时的照片进行像素对比
    UIImageView *imageView =[[UIImageView alloc] initWithFrame:CGRectMake(10, (SelfHeight - (SelfWidth - 20) /1.6)/2  + 170, SelfWidth - 20 , (SelfWidth - 20)/1.6)];
    imageView.image = imageIm;
    [self.view addSubview:imageView];

}

//截取图片
-(UIImage*)image:(UIImage *)imageI scaleToSize:(CGSize)size{
   /*
    UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
    CGSize size:指定将来创建出来的bitmap的大小
    BOOL opaque:设置透明YES代表透明,NO代表不透明
    CGFloat scale:代表缩放,0代表不缩放
    创建出来的bitmap就对应一个UIImage对象
    */
    UIGraphicsBeginImageContextWithOptions(size, NO, 2.0); //此处将画布放大两倍,这样在retina屏截取时不会影响像素
    
    [imageI drawInRect:CGRectMake(0, 0, size.width, size.height)];
    
    
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return scaledImage;
}
-(UIImage *)imageFromImage:(UIImage *)imageI inRect:(CGRect)rect{
    
    CGImageRef sourceImageRef = [imageI CGImage];
    
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
    
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    
    return newImage;
}


-(void)back{
    [self dismissViewControllerAnimated:NO completion:nil];
}

完整代码下载,GitHub:https://github.com/micaimanong/CameraDema   

原文地址:https://www.cnblogs.com/carlos-mm/p/6524604.html