自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

30分鐘搞定iOS自定義相機

移動開發(fā) iOS
最近公司的項目中用到了相機,由于不用系統(tǒng)的相機,UI給的相機切圖,必須自定義才可以。就花時間簡單研究了一下相機的自定義。

最近公司的項目中用到了相機,由于不用系統(tǒng)的相機,UI給的相機切圖,必須自定義才可以。就花時間簡單研究了一下相機的自定義。

相機屬于系統(tǒng)硬件,這就需要我們來手動調用iPhone的相機硬件,分為以下步驟:

1、首先聲明以下對象

  1. #import <AVFoundation/AVFoundation.h> 
  2. //捕獲設備,通常是前置攝像頭,后置攝像頭,麥克風(音頻輸入)  
  3. @property (nonatomic, strong) AVCaptureDevice *device;  
  4.  
  5. //AVCaptureDeviceInput 代表輸入設備,他使用AVCaptureDevice 來初始化  
  6. @property (nonatomic, strong) AVCaptureDeviceInput *input;  
  7.  
  8. //輸出圖片  
  9. @property (nonatomic ,strong) AVCaptureStillImageOutput *imageOutput;  
  10.  
  11. //session:由他把輸入輸出結合在一起,并開始啟動捕獲設備(攝像頭)  
  12. @property (nonatomic, strong) AVCaptureSession *session;  
  13.  
  14. //圖像預覽層,實時顯示捕獲的圖像  
  15. @property (nonatomic ,strong) AVCaptureVideoPreviewLayer *previewLayer; 

2、初始化各個對象

  1. - (void)cameraDistrict  
  2. {  
  3. //    AVCaptureDevicePositionBack  后置攝像頭  
  4. //    AVCaptureDevicePositionFront 前置攝像頭  
  5.    self.device = [self cameraWithPosition:AVCaptureDevicePositionFront];  
  6.     self.input = [[AVCaptureDeviceInput alloc] initWithDevice:self.device error:nil];  
  7.  
  8.     self.imageOutput = [[AVCaptureStillImageOutput alloc] init];  
  9.  
  10.     self.session = [[AVCaptureSession alloc] init];  
  11.     //     拿到的圖像的大小可以自行設定  
  12.     //    AVCaptureSessionPreset320x240  
  13.     //    AVCaptureSessionPreset352x288  
  14.     //    AVCaptureSessionPreset640x480  
  15.     //    AVCaptureSessionPreset960x540  
  16.     //    AVCaptureSessionPreset1280x720  
  17.     //    AVCaptureSessionPreset1920x1080  
  18.     //    AVCaptureSessionPreset3840x2160  
  19.     self.session.sessionPreset = AVCaptureSessionPreset640x480;  
  20.     //輸入輸出設備結合  
  21.     if ([self.session canAddInput:self.input]) {  
  22.         [self.session addInput:self.input];  
  23.     }  
  24.     if ([self.session canAddOutput:self.imageOutput]) {  
  25.         [self.session addOutput:self.imageOutput];  
  26.     }  
  27.     //預覽層的生成  
  28.     self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];  
  29.     self.previewLayer.frame = CGRectMake(0, 64, SCREEN_WIDTH, SCREEN_HEIGHT-64);  
  30.     self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;  
  31.     [self.view.layer addSublayer:self.previewLayer];  
  32.     //設備取景開始  
  33.     [self.session startRunning];  
  34.     if ([_device lockForConfiguration:nil]) {  
  35.     //自動閃光燈,  
  36.         if ([_device isFlashModeSupported:AVCaptureFlashModeAuto]) {  
  37.             [_device setFlashMode:AVCaptureFlashModeAuto];  
  38.         }  
  39.         //自動白平衡,但是好像一直都進不去  
  40.         if ([_device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {  
  41.             [_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];  
  42.         }  
  43.         [_device unlockForConfiguration];  
  44.     }  
  45.  

根據(jù)前后置位置拿到相應的攝像頭:

  1. - (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position{  
  2.     NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];  
  3.     for ( AVCaptureDevice *device in devices )  
  4.         if ( device.position == position ){  
  5.             return device;  
  6.         }  
  7.     return nil;  

3、拍照拿到相應圖片:

  1. - (void)photoBtnDidClick  
  2. {  
  3.     AVCaptureConnection *conntion = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];  
  4.       if (!conntion) {  
  5.           NSLog(@"拍照失敗!");  
  6.           return;  
  7.           }  
  8.     [self.imageOutput captureStillImageAsynchronouslyFromConnection:conntion completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {  
  9.         if (imageDataSampleBuffer == nil) {  
  10.             return ;  
  11.           }  
  12.         NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];  
  13.         self.image = [UIImage imageWithData:imageData];  
  14.         [self.session stopRunning];  
  15.         [self.view addSubview:self.cameraImageView];  

4、前后置攝像頭的切換

  1. - (void)changeCamera{  
  2.     NSUInteger cameraCount = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];  
  3.     if (cameraCount > 1) {  
  4.         NSError *error;  
  5.         //給攝像頭的切換添加翻轉動畫  
  6.         CATransition *animation = [CATransition animation];  
  7.         animation.duration = .5f;  
  8.         animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];  
  9.         animation.type = @"oglFlip";  
  10.  
  11.         AVCaptureDevice *newCamera = nil;  
  12.         AVCaptureDeviceInput *newInput = nil;  
  13.   //拿到另外一個攝像頭位置  
  14.         AVCaptureDevicePosition position = [[_input device] position];  
  15.         if (position == AVCaptureDevicePositionFront){  
  16.             newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];  
  17.             animation.subtype = kCATransitionFromLeft;//動畫翻轉方向  
  18.         }  
  19.         else {  
  20.             newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];  
  21.             animation.subtype = kCATransitionFromRight;//動畫翻轉方向  
  22.         }  
  23.         //生成新的輸入  
  24.         newInput = [AVCaptureDeviceInput deviceInputWithDevice:newCamera error:nil];  
  25.         [self.previewLayer addAnimation:animation forKey:nil];  
  26.         if (newInput != nil) {  
  27.             [self.session beginConfiguration];  
  28.             [self.session removeInput:self.input];  
  29.             if ([self.session canAddInput:newInput]) {  
  30.                 [self.session addInput:newInput];  
  31.                 self.input = newInput;  
  32.  
  33.             } else {  
  34.                 [self.session addInput:self.input];  
  35.             }  
  36.             [self.session commitConfiguration];  
  37.  
  38.         } else if (error) {  
  39.             NSLog(@"toggle carema failed, error = %@", error);  
  40.         }  
  41.     }  

5、相機的其它參數(shù)設置

  1. //AVCaptureFlashMode  閃光燈  
  2. //AVCaptureFocusMode  對焦  
  3. //AVCaptureExposureMode  曝光  
  4. //AVCaptureWhiteBalanceMode  白平衡  
  5. //閃光燈和白平衡可以在生成相機時候設置  
  6. //曝光要根據(jù)對焦點的光線狀況而決定,所以和對焦一塊寫  
  7. //point為點擊的位置  
  8. - (void)focusAtPoint:(CGPoint)point{  
  9.     CGSize size = self.view.bounds.size;  
  10.     CGPoint focusPoint = CGPointMake( point.y /size.height ,1-point.x/size.width );  
  11.     NSError *error;  
  12.     if ([self.device lockForConfiguration:&error]) {  
  13.         //對焦模式和對焦點  
  14.         if ([self.device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {  
  15.             [self.device setFocusPointOfInterest:focusPoint];  
  16.             [self.device setFocusMode:AVCaptureFocusModeAutoFocus];  
  17.         }  
  18.         //曝光模式和曝光點  
  19.         if ([self.device isExposureModeSupported:AVCaptureExposureModeAutoExpose ]) {  
  20.             [self.device setExposurePointOfInterest:focusPoint];  
  21.             [self.device setExposureMode:AVCaptureExposureModeAutoExpose];  
  22.         }  
  23.  
  24.         [self.device unlockForConfiguration];  
  25.         //設置對焦動畫  
  26.         _focusView.center = point;  
  27.         _focusView.hidden = NO;  
  28.         [UIView animateWithDuration:0.3 animations:^{  
  29.             _focusView.transform = CGAffineTransformMakeScale(1.25, 1.25);  
  30.         }completion:^(BOOL finished) {  
  31.             [UIView animateWithDuration:0.5 animations:^{  
  32.                 _focusView.transform = CGAffineTransformIdentity;  
  33.             } completion:^(BOOL finished) {  
  34.                 _focusView.hidden = YES;  
  35.             }];  
  36.         }];  
  37.     }  
  38.  

6、遇到的一些坑和解決辦法

1) 前后置攝像頭的切換

前后值不能切換,各種嘗試找了半天沒找到有原因。后來發(fā)現(xiàn)我在設置圖片尺寸的時候設置為1080P [self.session canSetSessionPreset: AVCaptureSessionPreset1920x1080] ,前置攝像頭并不支持這么大的尺寸,所以就不能切換前置攝像頭。我驗證了下 前置攝像頭最高支持720P,720P以內可自由切換。

當然也可以在前后置攝像頭切換的時候,根據(jù)前后攝像頭來設置不同的尺寸,這里不在贅述。

2)焦點位置

CGPoint focusPoint = CGPointMake( point.y /size.height ,1-point.x/size.width );

setExposurePointOfInterest:focusPoint 函數(shù)后面Point取值范圍是取景框左上角(0,0)到取景框右下角(1,1)之間。官方是這么寫的:

The value of this property is a CGPoint that determines the receiver's focus point of interest, if it has one. A value of (0,0) indicates that the camera should focus on the top left corner of the image, while a value of (1,1) indicates that it should focus on the bottom right. The default value is (0.5,0.5).

我也試了按這個來但位置就是不對,只能按上面的寫法才可以。前面是點擊位置的y/PreviewLayer的高度,后面是1-點擊位置的x/PreviewLayer的寬度

3)對焦和曝光

我在設置對焦是 先設置了模式setFocusMode,后設置對焦位置,就會導致很奇怪的現(xiàn)象,對焦位置是你上次點擊的位置。所以一定要先設置位置,再設置對焦模式。

曝光同上

7、寫在最后

附上demo:https://github.com/nanshanyi/photographDemo

常用到的基本就這么多,寫的并不完善,有什么不對的,歡迎大家批評指正,共同學習。

責任編輯:陳琳 來源: 簡書
相關推薦

2017-01-10 09:07:53

tcpdumpGET請求

2013-05-03 10:57:09

泛型泛型教程

2021-12-01 06:50:50

Docker底層原理

2015-01-14 15:06:48

定義相機

2020-05-22 10:20:27

Shiro架構字符串

2022-03-11 09:10:10

hooksReact自定義

2009-11-26 11:19:52

NIS服務器

2025-03-18 09:20:00

Go語言Golang

2011-05-26 09:03:17

JSONjavascript

2010-03-05 17:28:08

2018-03-20 16:46:03

Windows 10Windows部署更新

2017-07-18 11:10:45

2011-02-21 17:48:35

vsFTPd

2017-09-27 11:00:50

LinuxBash使用技巧

2013-06-24 15:32:41

JPush極光推送Android Pus移動開發(fā)

2023-04-12 11:18:51

甘特圖前端

2020-12-18 07:33:20

SpringSchedule組件

2023-11-30 10:21:48

虛擬列表虛擬列表工具庫

2013-12-11 10:00:14

C++新特性C

2017-06-07 18:40:33

PromiseJavascript前端
點贊
收藏

51CTO技術棧公眾號