• 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   

  • 相关阅读:
    2017年6月笔记
    2017年5月笔记
    2017年4月笔记
    转发:i p _ f o r w a r d函数
    IP分组
    IP协议首部结构介绍
    IP:网际协议
    sed工具使用
    正则表达式匹配
    TCP的半连接
  • 原文地址:https://www.cnblogs.com/carlos-mm/p/6524604.html
Copyright © 2020-2023  润新知