【iOS】自定义相机|自定义像素分辨率|自定义尺寸的照片

需求

需求:卖家版应用需要用到800*800的正方形照片才能上传;而且所见即所得,不能裁切照片。这就要求我们自定义相机界面、获取照片、处理。

说明

iOS 自定义相机 |(以后置拍照为例)
自定义像素分辨率 | (以800x800px为例)
自定义尺寸的照片 | (以正方形为例)

代码

#import 
 #import "UIImage+fixOrientation.h"
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
//强迫症的最爱
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@interface ViewController ()
//捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)
@property (nonatomic, strong) AVCaptureDevice *device;
//AVCaptureDeviceInput 代表输入设备,他使用AVCaptureDevice 来初始化
@property (nonatomic, strong) AVCaptureDeviceInput *input;
//输出图片
@property (nonatomic ,strong) AVCaptureStillImageOutput  *imageOutput;
//session:由他把输入输出结合在一起,并开始启动捕获设备(摄像头)
@property (nonatomic, strong) AVCaptureSession *session;
//图像预览层,实时显示捕获的图像
@property (nonatomic ,strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic ,strong) UIImage *image;
@property (nonatomic,strong)  UILabel * msgLabel;

@end
- (void)viewDidLoad {
    [super viewDidLoad];
    
    

    // ---------------------------------// ---------------------------------
    [self setupUI];
    // ---------------------------------// ---------------------------------
    [self cameraDistrict];
    
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    
    self.view.backgroundColor = [UIColor whiteColor];
    //设备取景开始
    [self.session startRunning];
    
    self.msgLabel.text = @"提示:点击拍照按钮";
}

- (void)setupUI {
    // ---------------------------------// ---------------------------------
        UIButton * photoBtn = [[UIButton alloc] init];
        photoBtn.frame = CGRectMake(SCREEN_WIDTH * 0.5 - 50, SCREEN_HEIGHT - 200, 100, 100);
        photoBtn.backgroundColor = [UIColor blackColor];
        [photoBtn addTarget:self action:@selector(photoBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
        [photoBtn setTitle:@"拍照" forState:UIControlStateNormal];
        [self.view addSubview:photoBtn];
    // ---------------------------------// ---------------------------------
        self.msgLabel = [[UILabel alloc] init];
        self.msgLabel.text = @"提示:点击拍照按钮";
        self.msgLabel.frame = CGRectMake(50, 100, SCREEN_WIDTH, 100);
        [self.view addSubview:self.msgLabel];
        self.msgLabel.textColor = [UIColor redColor];
        // ---------------------------------// ---------------------------------
        UISwitch * lightSwith = [[UISwitch alloc] initWithFrame:CGRectMake(50, 50, 100, 50)];
        [lightSwith addTarget:self action:@selector(lightClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:lightSwith];
}


- (void)cameraDistrict
{
    //    AVCaptureDevicePositionBack  后置摄像头
    //    AVCaptureDevicePositionFront 前置摄像头
    self.device = [self cameraWithPosition:AVCaptureDevicePositionBack];
    self.input = [[AVCaptureDeviceInput alloc] initWithDevice:self.device error:nil];
    
    self.imageOutput = [[AVCaptureStillImageOutput alloc] init];
    
    
    
    self.session = [[AVCaptureSession alloc] init];
    //     拿到的图像的大小可以自行设定
    //    AVCaptureSessionPresetHigh
    //    AVCaptureSessionPreset320x240
    //    AVCaptureSessionPreset352x288
    //    AVCaptureSessionPreset640x480
    //    AVCaptureSessionPreset960x540
    //    AVCaptureSessionPreset1280x720
    //    AVCaptureSessionPreset1920x1080
    //    AVCaptureSessionPreset3840x2160
    self.session.sessionPreset = AVCaptureSessionPreset1920x1080;
    //输入输出设备结合
    if ([self.session canAddInput:self.input]) {
        [self.session addInput:self.input];
    }
    if ([self.session canAddOutput:self.imageOutput]) {
        [self.session addOutput:self.imageOutput];
    }
    //预览层的生成
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    self.previewLayer.frame = CGRectMake(0, SCREEN_HEIGHT * 0.5 - SCREEN_WIDTH * 0.5, SCREEN_WIDTH, SCREEN_WIDTH);
    
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [self.view.layer addSublayer:self.previewLayer];
    //设备取景开始
    [self.session startRunning];
    if ([_device lockForConfiguration:nil]) {
        //自动闪光灯,
        
        if ([_device isFlashModeSupported:AVCaptureFlashModeAuto]) {
            [_device setFlashMode:AVCaptureFlashModeOff];
        }
        //自动白平衡,但是好像一直都进不去
        if ([_device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
            [_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
        }
        [_device unlockForConfiguration];
    }
    
}
//闪光灯开关
- (void)lightClick: (UISwitch *)lightSwitch{
    if (lightSwitch.isOn) {
        
        
        if ([_device lockForConfiguration:nil]) {
            //自动闪光灯,
            
            if ([_device isFlashModeSupported:AVCaptureFlashModeAuto]) {
                [_device setFlashMode:AVCaptureFlashModeAuto];
            }
            
        }
    }else {
        
        if ([_device lockForConfiguration:nil]) {
            //自动闪光灯,
            
            if ([_device isFlashModeSupported:AVCaptureFlashModeAuto]) {
                [_device setFlashMode:AVCaptureFlashModeOff];
            }
            
        }
    }
    
}

///拍照点击
- (void)photoBtnDidClick
{
    AVCaptureConnection *conntion = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
    if (!conntion) {
        NSLog(@"拍照失败!");
        return;
    }
    [self.imageOutput captureStillImageAsynchronouslyFromConnection:conntion completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        if (imageDataSampleBuffer == nil) {
            return ;
        }
        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
        self.image = [UIImage imageWithData:imageData];
        [self.session stopRunning];
        self.image = [self cropImage:self.image toRect:CGRectMake(0, (self.image.size.height - self.image.size.width) * 0.5, self.image.size.width, self.image.size.width)];
        
        
        CGFloat width = 800;//宽度
        CGFloat height = 800;//高度
        
        UIGraphicsBeginImageContext(CGSizeMake(width, height));
        [self.image drawInRect:CGRectMake(0,0, width, height)];
        self.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        [self saveImageToPhotoAlbum:self.image];
    }];
    
}

- (UIImage *)cropImage:(UIImage *)image toRect:(CGRect)rect {
    
    CGFloat x = rect.origin.x;
    
    CGFloat y = rect.origin.y;
    
    CGFloat width = rect.size.width;
    
    CGFloat height = rect.size.height;
    
    CGRect croprect = CGRectMake(floor(x), floor(y), round(width), round(height));
    
    UIImage *toCropImage = [image fixOrientation];// 纠正方向
    
    CGImageRef cgImage = CGImageCreateWithImageInRect(toCropImage.CGImage, croprect);
    
    UIImage *cropped = [UIImage imageWithCGImage:cgImage];
    
    CGImageRelease(cgImage);
    
    return cropped;
    
}

效果

UI界面仅供参考

UI界面仅供参考

[800*800成品照片]

800*800成品照片

[苹果相册不支持查看相片信息,我们借助第三方APP确认]

苹果相册不支持查看相片信息,我们借助第三方APP确认

你可能感兴趣的:(【iOS】自定义相机|自定义像素分辨率|自定义尺寸的照片)