11 相機的使用

/*? 自定義相機:四個核心對象;前后攝像頭的對調(diào);拍照和保存;裁剪圖片;水印圖片;? */

#import "TwoViewController.h"

#import<AVFoundation/AVFoundation.h>

@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;

//都是輸出設(shè)備

//@property (nonatomic,strong) AVCapturePhotoOutput *output;

@property (nonatomic,strong) AVCaptureStillImageOutput *output;

@property (nonatomic,strong) AVCaptureSession *session;

//預(yù)覽圖層,取景框? 添加到layer上

@property (nonatomic,weak) AVCaptureVideoPreviewLayer *pre_Layer;

@end

@implementation TwoViewController

//旋轉(zhuǎn)按鈕

- (IBAction)rotateCamera:(id)sender {

//獲取翻轉(zhuǎn)后的攝像頭,給會話

AVCaptureDevice *device = [self captureDevice];

AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];

//從會話中刪除攝像頭

[self.session removeInput:self.deviceInput];

//停止會話

[self.session stopRunning];

//將輸入設(shè)備添加到會話中,如果會話中有輸入設(shè)備,不能再進入新的涉嫌頭設(shè)備 需要刪除之前的攝像頭

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;

//獲取輸入設(shè)備

NSArray *array = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

AVCaptureDevice *device;

for (AVCaptureDevice *obj in array) {

if (position == obj.position) {

device = obj;

break;

}

}

return? device;

}

- (void)setupSession {

//輸入設(shè)備

//獲取設(shè)備 攝像頭有兩個

//? ? 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];

}

//創(chuàng)建取景框? 預(yù)覽圖層

AVCaptureVideoPreviewLayer *preViewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];

self.pre_Layer = preViewLayer;

//設(shè)置大小

CGRect rect = [UIScreen mainScreen].bounds;

rect.size.height -= 126;

self.pre_Layer.frame = rect;

//最好在viewWillLayoutSubviews設(shè)置? viewDidLoad里設(shè)置顯示不出來

//取景框添加到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);

//輸入設(shè)備? 獲取圖片

[self.output captureStillImageAsynchronouslyFromConnection:self.output.connections.firstObject completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

if (error) {

NSLog(@"%@",error);

return ;

}

//獲取圖片的二進制數(shù)據(jù)

NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

UIImage *image = [UIImage imageWithData:data];

//獲取預(yù)覽視圖的大小

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();

//關(guān)閉圖形上下文

UIGraphicsEndImageContext();

//保存圖片到相冊

UIImageWriteToSavedPhotosAlbum(finalImage, self, @selector(image: didFinishSavingWithError:contextInfo:), nil);

}];

}

//保存圖片到相冊之后的回調(diào)? 成功失敗都會調(diào)用此方法

- (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];

//攝像頭輸入設(shè)備;如相數(shù)據(jù)輸出;拍攝會話連接前兩個;取景框,預(yù)覽圖層,也要加在會話中? ? 連接完成之后,將會話給layer,layer使用會話

//? ? [self dismissViewControllerAnimated:YES completion:nil];

}

- (BOOL)prefersStatusBarHidden {

return YES;

}

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容