/* 自定义相机:四个核心对象;前后摄像头的对调;拍照和保存;裁剪图片;水印图片; */
#import "TwoViewController.h"
#import
@interface TwoViewController ()
@property (nonatomic,strong) AVCaptureDeviceInput *deviceInput;
@property (weak, nonatomic) IBOutlet UIImageView *waterPrintImageView;
@property (weak, nonatomic) IBOutlet UILabel *sportDistanceLabel;
@property (weak, nonatomic) IBOutlet UILabel *tipLabel;
@property (weak, nonatomic) IBOutlet UIButton *captureBtn;
//都是输出设备
//@property (nonatomic,strong) AVCapturePhotoOutput *output;
@property (nonatomic,strong) AVCaptureStillImageOutput *output;
@property (nonatomic,strong) AVCaptureSession *session;
//预览图层,取景框 添加到layer上
@property (nonatomic,weak) AVCaptureVideoPreviewLayer *pre_Layer;
@end
@implementation TwoViewController
//旋转按钮
- (IBAction)rotateCamera:(id)sender {
//获取翻转后的摄像头,给会话
AVCaptureDevice *device = [self captureDevice];
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//从会话中删除摄像头
[self.session removeInput:self.deviceInput];
//停止会话
[self.session stopRunning];
//将输入设备添加到会话中,如果会话中有输入设备,不能再进入新的涉嫌头设备 需要删除之前的摄像头
if ([self.session canAddInput:deviceInput]) {
[self.session addInput:deviceInput];
//开始会话
[self.session startRunning];
self.deviceInput = deviceInput;
}
}
//抽取方法
- (AVCaptureDevice *)captureDevice {
//获取相机位置
AVCaptureDevicePosition position = (self.deviceInput.device.position != AVCaptureDevicePositionBack) ? AVCaptureDevicePositionBack : AVCaptureDevicePositionFront;
//获取输入设备
NSArray *array = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *device;
for (AVCaptureDevice *obj in array) {
if (position == obj.position) {
device = obj;
break;
}
}
return device;
}
- (void)setupSession {
//输入设备
//获取设备 摄像头有两个
// NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
// 获取后置摄像头
// AVCaptureDevice *backDevice;
//
// for (AVCaptureDevice *device in devices) {
//
// if (device.position == AVCaptureDevicePositionBack) {
//
// backDevice = device;
// break;
// }
//
//
// }
//获取后置摄像头
// AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *device = [self captureDevice];
self.deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
// self.output = [[AVCapturePhotoOutput alloc]init];
self.output = [[AVCaptureStillImageOutput alloc]init];
//会话
self.session = [[AVCaptureSession alloc]init];
if ([self.session canAddInput:self.deviceInput]) {
[self.session addInput:self.deviceInput];
}
if ([self.session canAddOutput:self.output]) {
[self.session addOutput:self.output];
}
//创建取景框 预览图层
AVCaptureVideoPreviewLayer *preViewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
self.pre_Layer = preViewLayer;
//设置大小
CGRect rect = [UIScreen mainScreen].bounds;
rect.size.height -= 126;
self.pre_Layer.frame = rect;
//最好在viewWillLayoutSubviews设置 viewDidLoad里设置显示不出来
//取景框添加到layer上
[self.view.layer addSublayer:preViewLayer];
//开启会话 取景框大小跟不上 取景框不能被压缩,高度变矮,宽度不变,图片变形
self.pre_Layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self startSession];
}
- (void)startSession {
[self.session startRunning];
}
- (void)stopSession {
[self.session stopRunning];
}
- (IBAction)cancelBtn:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)startCapture:(id)sender {
[self saveImage];
}
//保存照片,拍照和分享
- (void)saveImage {
//AVCaptureConnection 摄像头和照片的连接
NSLog(@"%@",self.output.connections);
//输入设备 获取图片
[self.output captureStillImageAsynchronouslyFromConnection:self.output.connections.firstObject completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (error) {
NSLog(@"%@",error);
return ;
}
//获取图片的二进制数据
NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:data];
//获取预览视图的大小
CGRect rect = self.pre_Layer.bounds;
//开启图形上下文
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0);
//画图片 CGRectInset 矩形两端裁剪 返回的是中间的大小
[image drawInRect:CGRectInset(rect, 0, -(self.view.bounds.size.height - rect.size.height) * 0.5)];
//画水印图片
[self.waterPrintImageView.image drawInRect:_waterPrintImageView.frame];
//运动距离的文字
[self.sportDistanceLabel.attributedText drawInRect:_sportDistanceLabel.frame];
//获取最新的图片
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭图形上下文
UIGraphicsEndImageContext();
//保存图片到相册
UIImageWriteToSavedPhotosAlbum(finalImage, self, @selector(image: didFinishSavingWithError:contextInfo:), nil);
}];
}
//保存图片到相册之后的回调 成功失败都会调用此方法
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
[self stopSession];
NSString *str = (error == nil) ? @"保存成功" : @"保存失败";
NSLog(@"%@",str);
self.tipLabel.text = str;
[UIView animateWithDuration:2 animations:^{
self.tipLabel.alpha = 1;
} completion:^(BOOL finished) {
self.tipLabel.alpha = 0;
}];
}
- (void)viewDidLoad {
[super viewDidLoad];
// BOOL isEmptyTitle = (self.captureBtn.currentTitle == nil); 为空 返回YES ;不为空 返回NO
[self setupSession];
//摄像头输入设备;如相数据输出;拍摄会话连接前两个;取景框,预览图层,也要加在会话中 连接完成之后,将会话给layer,layer使用会话
// [self dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
@end