iOS中如何使用視聽媒體框架AVFoundation實現(xiàn)照片拍攝-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)iOS中如何使用視聽媒體框架AVFoundation實現(xiàn)照片拍攝,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)專注于西山網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供西山營銷型網(wǎng)站建設(shè),西山網(wǎng)站制作、西山網(wǎng)頁設(shè)計、西山網(wǎng)站官網(wǎng)定制、微信小程序服務(wù),打造西山網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供西山網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

下面貼上核心控制器代碼:

#import "HWPhotoVC.h"#import <AVFoundation/AVFoundation.h>@interface HWPhotoVC ()@property (nonatomic, strong) AVCaptureSession *captureSession;//負(fù)責(zé)輸入和輸出設(shè)備之間的數(shù)據(jù)傳遞@property (nonatomic, strong) AVCaptureDeviceInput *captureDeviceInput;//負(fù)責(zé)從AVCaptureDevice獲得輸入數(shù)據(jù)@property (nonatomic, strong) AVCaptureStillImageOutput *captureStillImageOutput;//照片輸出流@property (nonatomic, strong) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;//相機(jī)拍攝預(yù)覽圖層@property (nonatomic, weak) UIView *containerView;//內(nèi)容視圖@property (nonatomic, weak) UIImageView *focusCursor;//聚焦按鈕@property (nonatomic, weak) UIImageView *imgView;//拍攝照片@end@implementation HWPhotoVC- (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"拍照"; self.view.backgroundColor = [UIColor whiteColor]; //創(chuàng)建控件 [self creatControl];}- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //初始化信息 [self initPhotoInfo];}- (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; [self.captureSession startRunning];}- (void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:animated]; [self.captureSession stopRunning];}- (void)creatControl{ CGFloat btnW = 150.f; CGFloat btnH = 40.f; CGFloat marginY = 20.f; CGFloat w = [UIScreen mainScreen].bounds.size.width; CGFloat h = [UIScreen mainScreen].bounds.size.height; //內(nèi)容視圖 CGFloat containerViewH = h - 64 - btnH - marginY * 3; UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(10, 64 + marginY, w - 20, containerViewH)]; containerView.backgroundColor = [UIColor whiteColor]; containerView.layer.borderWidth = 1.f; containerView.layer.borderColor = [[UIColor grayColor] CGColor]; [self.view addSubview:containerView]; _containerView = containerView; //攝像頭切換按鈕 CGFloat cameraSwitchBtnW = 50.f; CGFloat cameraSwitchBtnMargin = 10.f; UIButton *cameraSwitchBtn = [[UIButton alloc] initWithFrame:CGRectMake(containerView.bounds.size.width - cameraSwitchBtnW - cameraSwitchBtnMargin, 64 + marginY + cameraSwitchBtnMargin, cameraSwitchBtnW, cameraSwitchBtnW)]; [cameraSwitchBtn setImage:[UIImage imageNamed:@"camera_switch"] forState:UIControlStateNormal]; [cameraSwitchBtn addTarget:self action:@selector(cameraSwitchBtnOnClick) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:cameraSwitchBtn]; //聚焦圖片 UIImageView *focusCursor = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 75, 75)]; focusCursor.alpha = 0; focusCursor.image = [UIImage imageNamed:@"camera_focus_red"]; [containerView addSubview:focusCursor]; _focusCursor = focusCursor; //拍攝照片容器 UIImageView *imgView = [[UIImageView alloc] initWithFrame:containerView.frame]; imgView.hidden = YES; imgView.layer.borderWidth = 1.f; imgView.layer.borderColor = [[UIColor grayColor] CGColor]; imgView.contentMode = UIViewContentModeScaleAspectFill; imgView.clipsToBounds = YES; [self.view addSubview:imgView]; _imgView = imgView; //按鈕 NSArray *titleArray = @[@"拍攝照片", @"重新拍攝"]; CGFloat btnY = CGRectGetMaxY(containerView.frame) + marginY; CGFloat margin = (w - btnW * titleArray.count) / (titleArray.count + 1); for (int i = 0; i < titleArray.count; i++) {  CGFloat btnX = margin + (margin + btnW) * i;  UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(btnX, btnY, btnW, btnH)];  btn.tag = 1000 + i;  [btn setTitle:titleArray[i] forState:UIControlStateNormal];  btn.backgroundColor = [UIColor orangeColor];  btn.layer.cornerRadius = 2.0f;  btn.layer.masksToBounds = YES;  if (i == 1) {   btn.hidden = YES;  }  [btn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside];  [self.view addSubview:btn]; }}- (void)initPhotoInfo{ //初始化會話 _captureSession = [[AVCaptureSession alloc] init]; //設(shè)置分辨率 if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) {  _captureSession.sessionPreset = AVCaptureSessionPreset1280x720; } //獲得輸入設(shè)備,取得后置攝像頭 AVCaptureDevice *captureDevice = [self getCameraDeviceWithPosition:AVCaptureDevicePositionBack]; if (!captureDevice) {  NSLog(@"取得后置攝像頭時出現(xiàn)問題");  return; } NSError *error = nil; //根據(jù)輸入設(shè)備初始化設(shè)備輸入對象,用于獲得輸入數(shù)據(jù) _captureDeviceInput = [[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error]; if (error) {  NSLog(@"取得設(shè)備輸入對象時出錯,錯誤原因:%@", error.localizedDescription);  return; } //初始化設(shè)備輸出對象,用于獲得輸出數(shù)據(jù) _captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary *outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG}; //輸出設(shè)置 [_captureStillImageOutput setOutputSettings:outputSettings]; //將設(shè)備輸入添加到會話中 if ([_captureSession canAddInput:_captureDeviceInput]) {  [_captureSession addInput:_captureDeviceInput]; } //將設(shè)備輸出添加到會話中 if ([_captureSession canAddOutput:_captureStillImageOutput]) {  [_captureSession addOutput:_captureStillImageOutput]; } //創(chuàng)建視頻預(yù)覽層,用于實時展示攝像頭狀態(tài) _captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; //攝像頭方向 AVCaptureConnection *captureConnection = [self.captureVideoPreviewLayer connection]; captureConnection.videoOrientation = AVCaptureVideoOrientationPortrait; CALayer *layer = _containerView.layer; layer.masksToBounds = YES; _captureVideoPreviewLayer.frame = layer.bounds; //填充模式 _captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; //將視頻預(yù)覽層添加到界面中 [layer insertSublayer:_captureVideoPreviewLayer below:self.focusCursor.layer]; [self addNotificationToCaptureDevice:captureDevice]; [self addGenstureRecognizer];}- (void)btnOnClick:(UIButton *)btn{ if (btn.tag == 1000) {  //拍攝照片  [self photoBtnOnClick]; }else if (btn.tag == 1001) {  //重新拍攝  [self resetPhoto]; }}#pragma mark 拍照- (void)photoBtnOnClick{ //根據(jù)設(shè)備輸出獲得連接 AVCaptureConnection *captureConnection = [self.captureStillImageOutput connectionWithMediaType:AVMediaTypeVideo]; captureConnection.videoOrientation = AVCaptureVideoOrientationPortrait; //根據(jù)連接取得設(shè)備輸出的數(shù)據(jù) [self.captureStillImageOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {  if (imageDataSampleBuffer) {   NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];   UIImage *image = [UIImage imageWithData:imageData];   _imgView.image = image;   _imgView.hidden = NO;  } }]; UIButton *btn = (UIButton *)[self.view viewWithTag:1001]; btn.hidden = NO;}//重新拍攝- (void)resetPhoto{ _imgView.hidden = YES; UIButton *btn = (UIButton *)[self.view viewWithTag:1001]; btn.hidden = YES;}#pragma mark - 通知//給輸入設(shè)備添加通知- (void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{ //注意添加區(qū)域改變捕獲通知必須首先設(shè)置設(shè)備允許捕獲 [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {  captureDevice.subjectAreaChangeMonitoringEnabled = YES; }]; //捕獲區(qū)域發(fā)生改變 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];}- (void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{ [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];}//移除所有通知- (void)removeNotification{ [[NSNotificationCenter defaultCenter] removeObserver:self];}//設(shè)備連接成功- (void)deviceConnected:(NSNotification *)notification{ NSLog(@"設(shè)備已連接...");}//設(shè)備連接斷開- (void)deviceDisconnected:(NSNotification *)notification{ NSLog(@"設(shè)備已斷開.");}//捕獲區(qū)域改變- (void)areaChange:(NSNotification *)notification{ NSLog(@"捕獲區(qū)域改變...");}#pragma mark - 私有方法//取得指定位置的攝像頭- (AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{ NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *camera in cameras) {  if ([camera position] == position) {   return camera;  } } return nil;}#pragma mark 切換前后攝像頭- (void)cameraSwitchBtnOnClick{ AVCaptureDevice *currentDevice = [self.captureDeviceInput device]; AVCaptureDevicePosition currentPosition = [currentDevice position]; [self removeNotificationFromCaptureDevice:currentDevice]; AVCaptureDevice *toChangeDevice; AVCaptureDevicePosition toChangePosition = AVCaptureDevicePositionFront; if (currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionFront) {  toChangePosition = AVCaptureDevicePositionBack; } toChangeDevice = [self getCameraDeviceWithPosition:toChangePosition]; [self addNotificationToCaptureDevice:toChangeDevice]; //獲得要調(diào)整的設(shè)備輸入對象 AVCaptureDeviceInput *toChangeDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:toChangeDevice error:nil]; //改變會話的配置前一定要先開啟配置,配置完成后提交配置改變 [self.captureSession beginConfiguration]; //移除原有輸入對象 [self.captureSession removeInput:self.captureDeviceInput]; //添加新的輸入對象 if ([self.captureSession canAddInput:toChangeDeviceInput]) {  [self.captureSession addInput:toChangeDeviceInput];  self.captureDeviceInput = toChangeDeviceInput; } //提交會話配置 [self.captureSession commitConfiguration];}//改變設(shè)備屬性的統(tǒng)一操作方法- (void)changeDeviceProperty:(void (^)(AVCaptureDevice *))propertyChange{ AVCaptureDevice *captureDevice = [self.captureDeviceInput device]; NSError *error; //注意改變設(shè)備屬性前一定要首先調(diào)用lockForConfiguration:調(diào)用完之后使用unlockForConfiguration方法解鎖 if ([captureDevice lockForConfiguration:&error]) {  propertyChange(captureDevice);  [captureDevice unlockForConfiguration]; }else {  NSLog(@"設(shè)置設(shè)備屬性過程發(fā)生錯誤,錯誤信息:%@", error.localizedDescription); }}//設(shè)置閃光燈模式- (void)setFlashMode:(AVCaptureFlashMode)flashMode{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {  if ([captureDevice isFlashModeSupported:flashMode]) {   [captureDevice setFlashMode:flashMode];  } }];}//設(shè)置聚焦模式- (void)setFocusMode:(AVCaptureFocusMode)focusMode{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {  if ([captureDevice isFocusModeSupported:focusMode]) {   [captureDevice setFocusMode:focusMode];  } }];}//設(shè)置曝光模式- (void)setExposureMode:(AVCaptureExposureMode)exposureMode{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {  if ([captureDevice isExposureModeSupported:exposureMode]) {   [captureDevice setExposureMode:exposureMode];  } }];}//設(shè)置聚焦點- (void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {  if ([captureDevice isFocusModeSupported:focusMode]) {   [captureDevice setFocusMode:AVCaptureFocusModeAutoFocus];  }  if ([captureDevice isFocusPointOfInterestSupported]) {   [captureDevice setFocusPointOfInterest:point];  }  if ([captureDevice isExposureModeSupported:exposureMode]) {   [captureDevice setExposureMode:AVCaptureExposureModeAutoExpose];  }  if ([captureDevice isExposurePointOfInterestSupported]) {   [captureDevice setExposurePointOfInterest:point];  } }];}//添加點按手勢,點按時聚焦- (void)addGenstureRecognizer{ [self.containerView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapScreen:)]];}- (void)tapScreen:(UITapGestureRecognizer *)tapGesture{ CGPoint point = [tapGesture locationInView:self.containerView]; //將UI坐標(biāo)轉(zhuǎn)化為攝像頭坐標(biāo) CGPoint cameraPoint = [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point]; [self setFocusCursorWithPoint:point]; [self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint];}//設(shè)置聚焦光標(biāo)位置- (void)setFocusCursorWithPoint:(CGPoint)point{ self.focusCursor.center = point; self.focusCursor.transform = CGAffineTransformMakeScale(1.5, 1.5); self.focusCursor.alpha = 1.0; [UIView animateWithDuration:1.0 animations:^{  self.focusCursor.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) {  self.focusCursor.alpha = 0; }];}- (void)dealloc{ [self removeNotification];}@end

關(guān)于“iOS中如何使用視聽媒體框架AVFoundation實現(xiàn)照片拍攝”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

當(dāng)前標(biāo)題:iOS中如何使用視聽媒體框架AVFoundation實現(xiàn)照片拍攝-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://muchs.cn/article40/dchheo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、靜態(tài)網(wǎng)站、小程序開發(fā)、營銷型網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈品牌網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站