iOS 拍照
2019-01-07 本文已影响0人
索性流年
使用系统框架AVFoundation下的:
<AVCapturePhotoCaptureDelegate>进行拍照
创建LyPhotoCollection继承与UIView
.h
#import <AVFoundation/AVFoundation.h>
#import <Photos/Photos.h>
//回调
@property(nonatomic,copy)void (^photoComesBlack) (UIImage *photoImage);
//拍照
-(void)shutterCamera;
// 闪光灯开关
-(void)lightAction;
//停止运行
-(void)stopRunning;
//开始运行
-(void)startRunning;
/**
切换前后摄像头
@param camera 前置、后置
*/
- (void)cameraPosition:(NSString *)camera;
//照片保存到相册
- (void)saveImageWithImage:(UIImage *)image;
//放大缩小屏幕
- (void)viewScaleChnageValue:(CGFloat )sender;
.m
@interface LyPhotoCollection () <AVCapturePhotoCaptureDelegate>
@property (nonatomic, strong) AVCaptureSession *captureSession; // 会话
@property (nonatomic, strong) AVCaptureDevice * captureDevice; // 输入设备
@property (nonatomic, strong) AVCaptureDeviceInput * captureDeviceInput; // 输入源
@property (nonatomic, strong) AVCapturePhotoOutput *photoOutput; // 图像输出
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; // 预览画面
@property (nonatomic, strong) AVCapturePhotoSettings *photoSettings; // 图像设置
@property (nonatomic, assign) AVCaptureFlashMode mode;
@property (nonatomic, assign) AVCaptureDevicePosition position;
@end
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self.layer insertSublayer:self.previewLayer atIndex:0];
// 5. 连接输入与会话
if ([self.captureSession canAddInput:self.captureDeviceInput]) {
[self.captureSession addInput:self.captureDeviceInput];
}
// 6. 连接输出与会话
if ([self.captureSession canAddOutput:self.photoOutput]) {
[self.captureSession addOutput:self.photoOutput];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationWillEnterForegroundNotification object:nil];
}
return self;
}
#pragma mark - 监听是否重新进入程序程序
-(void)applicationDidBecomeActive{
if (self.captureSession.isRunning != YES) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.captureSession startRunning];
});
}
}
-(void)layoutSubviews{
[super layoutSubviews];
self.previewLayer.frame = self.bounds;
// [self.previewLayer removeFromSuperlayer];
[self startRunning];
}
#pragma mark - 开始运行
-(void)startRunning{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[self.captureSession startRunning];
});
}
#pragma mark - 停止运行
-(void)stopRunning{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[self.captureSession stopRunning];
});
}
#pragma mark - 调整焦距
- (void)cameraBackgroundDidChangeFocus:(CGFloat)focus{
AVCaptureDevice *captureDevice = [self.captureDeviceInput device];
NSError *error;
if ([captureDevice lockForConfiguration:&error]) {
if ([captureDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]){
[captureDevice setFocusModeLockedWithLensPosition:focus completionHandler:nil];
}
}
else{
// Handle the error appropriately.
}
}
#pragma mark - 放大缩小屏幕
- (void)viewScaleChnageValue:(CGFloat )sender
{
self.transform = CGAffineTransformMakeScale(sender, sender);
}
#pragma mark - 拍照
-(void)shutterCamera{
self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey:AVVideoCodecJPEG}];
[self.photoSettings setFlashMode:self.mode];
if (!self.previewLayer || !self.photoOutput || !self.photoSettings) {
return;
}
if (self.captureSession.isRunning == YES) {
[self.photoOutput capturePhotoWithSettings:self.photoSettings delegate:self];
}
}
#pragma mark - 闪光灯开关
-(void)lightAction{
if (self.mode == AVCaptureFlashModeOn) {
[self setMode:AVCaptureFlashModeOff];
} else {
[self setMode:AVCaptureFlashModeOn];
}
}
#pragma mark - 切换前后摄像头
- (void)cameraPosition:(NSString *)camera{
if ([camera isEqualToString:@"前置"]) {
if (self.captureDevice.position != AVCaptureDevicePositionFront) {
self.position = AVCaptureDevicePositionFront;
}
}
else if ([camera isEqualToString:@"后置"]){
if (self.captureDevice.position != AVCaptureDevicePositionBack) {
self.position = AVCaptureDevicePositionBack;
}
}
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:self.position];
if (device) {
self.captureDevice = device;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];
[self.captureSession beginConfiguration];
[self.captureSession removeInput:self.captureDeviceInput];
if ([self.captureSession canAddInput:input]) {
[self.captureSession addInput:input];
self.captureDeviceInput = input;
[self.captureSession commitConfiguration];
}
}
}
#pragma mark - 拍照回调代理
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error{
if (!error) {
NSData *imageData = [photo fileDataRepresentation];
UIImage *image = [self transfor:[UIImage imageWithData:imageData]];
[self saveImageWithImage:image];
if (image) {
if (self.photoBlack) {
self.photoBlack(image);
}
[self saveImageWithImage:image];
}
}
}
#pragma mark - 解决图片绘制自动旋转90度的问题
-(UIImage *)transfor:(UIImage *)image{
int destWidth = image.size.width;
int destHeight = image.size.height;
UIGraphicsBeginImageContext(CGSizeMake(destWidth, destHeight));
[image drawInRect:CGRectMake(0,0,destWidth, destHeight)];
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
#pragma mark - 保存图片到相册
- (void)saveImageWithImage:(UIImage *)image{
// // 判断授权状态
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status != PHAuthorizationStatusAuthorized) return;
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
// 保存相片到相机胶卷
__block PHObjectPlaceholder *createdAsset = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
createdAsset = [PHAssetCreationRequest creationRequestForAssetFromImage:image].placeholderForCreatedAsset;
} error:&error];
if (error) {
NSLog(@"保存失败:%@", error);
return;
}
});
}];
}
-(AVCaptureDevicePosition)position{
if (!_position) {
_position = AVCaptureDevicePositionFront;
}
return _position;
}
#pragma mark - 创建会话
-(AVCaptureSession *)captureSession{
if (!_captureSession) {
_captureSession = [[AVCaptureSession alloc] init];
_captureSession.sessionPreset = AVCaptureSessionPresetPhoto; // 画质
}
return _captureSession;
}
#pragma mark - 创建输入设备
-(AVCaptureDevice *)captureDevice{
if (!_captureDevice) {
// 设置默认前置摄像头
_captureDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
}
return _captureDevice;
}
#pragma mark - 创建输入源
-(AVCaptureDeviceInput *)captureDeviceInput{
if (!_captureDeviceInput) {
_captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];
}
return _captureDeviceInput;
}
#pragma mark - 创建图像输出
-(AVCapturePhotoOutput *)photoOutput{
if (!_photoOutput) {
_photoOutput = [[AVCapturePhotoOutput alloc] init];
}
return _photoOutput;
}
-(AVCaptureVideoPreviewLayer *)previewLayer{
if (!_previewLayer) {
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
}
return _previewLayer;
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
调用拍照方法
//引入头文件
#import "LyPhotoCollection.h"
//拍照视图
@property(nonatomic,strong)LyPhotoCollection * lyPhotoV;
//加入视图
[self.view addSubview:self.lyPhotoV];
#pragma mark - 拍照视图
-(LyPhotoCollection *)lyPhotoV{
if (!_lyPhotoV) {
_lyPhotoV = [[LyPhotoCollection alloc]init];
}
return _lyPhotoV;
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
_lyPhotoV.frame = self.view.bounds;
}
//在需要的地方调用拍照
[_lyPhotoV shutterCamera];