转自:http://blog.csdn.net/qq_30513483/article/details/51198464
最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究了一下相机的自定义。
相机属于系统硬件,这就需要我们来手动调用iPhone的相机硬件,分为以下步骤:
![](https://i-blog.csdnimg.cn/blog_migrate/0518259a57a711c7c6cd75b5aba743c6.webp?x-image-process=image/format,png)
1、首先声明以下对象
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;"><span class="hljs-preprocessor" style="color: rgb(203, 75, 22);">#import <span class="hljs-title" style="color: rgb(38, 139, 210);"><AVFoundation/AVFoundation.h></span></span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">@property</span> (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">nonatomic</span>, <span class="hljs-keyword" style="color: rgb(133, 153, 0);">strong</span>) <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevice</span> *device; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//AVCaptureDeviceInput 代表输入设备,他使用AVCaptureDevice 来初始化</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">@property</span> (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">nonatomic</span>, <span class="hljs-keyword" style="color: rgb(133, 153, 0);">strong</span>) <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDeviceInput</span> *input; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//输出图片</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">@property</span> (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">nonatomic</span> ,<span class="hljs-keyword" style="color: rgb(133, 153, 0);">strong</span>) <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureStillImageOutput</span> *imageOutput; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//session:由他把输入输出结合在一起,并开始启动捕获设备(摄像头)</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">@property</span> (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">nonatomic</span>, <span class="hljs-keyword" style="color: rgb(133, 153, 0);">strong</span>) <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureSession</span> *session; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//图像预览层,实时显示捕获的图像</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">@property</span> (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">nonatomic</span> ,<span class="hljs-keyword" style="color: rgb(133, 153, 0);">strong</span>) <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureVideoPreviewLayer</span> *previewLayer;</code>
2、初始化各个对象
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;">- (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span>)cameraDistrict { <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureDevicePositionBack 后置摄像头</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureDevicePositionFront 前置摄像头</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> = [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span> cameraWithPosition:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevicePositionFront</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.input</span> = [[<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDeviceInput</span> alloc] initWithDevice:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> error:<span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.imageOutput</span> = [[<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureStillImageOutput</span> alloc] init]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> = [[<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureSession</span> alloc] init]; <span class="hljs-comment" style="color: rgb(147, 161, 161);">// 拿到的图像的大小可以自行设定</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset320x240</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset352x288</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset640x480</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset960x540</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset1280x720</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset1920x1080</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">// AVCaptureSessionPreset3840x2160</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.sessionPreset</span> = <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureSessionPreset640x480</span>; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//输入输出设备结合</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> canAddInput:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.input</span>]) { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> addInput:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.input</span>]; } <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> canAddOutput:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.imageOutput</span>]) { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> addOutput:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.imageOutput</span>]; } <span class="hljs-comment" style="color: rgb(147, 161, 161);">//预览层的生成</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.previewLayer</span> = [[<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureVideoPreviewLayer</span> alloc] initWithSession:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.previewLayer</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.frame</span> = <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGRectMake</span>(<span class="hljs-number" style="color: rgb(42, 161, 152);">0</span>, <span class="hljs-number" style="color: rgb(42, 161, 152);">64</span>, SCREEN_WIDTH, SCREEN_HEIGHT-<span class="hljs-number" style="color: rgb(42, 161, 152);">64</span>); <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.previewLayer</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.videoGravity</span> = <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVLayerVideoGravityResizeAspectFill</span>; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.view</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.layer</span> addSublayer:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.previewLayer</span>]; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//设备取景开始</span> [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> startRunning]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([_device lockForConfiguration:<span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>]) { <span class="hljs-comment" style="color: rgb(147, 161, 161);">//自动闪光灯,</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([_device isFlashModeSupported:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureFlashModeAuto</span>]) { [_device setFlashMode:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureFlashModeAuto</span>]; } <span class="hljs-comment" style="color: rgb(147, 161, 161);">//自动白平衡,但是好像一直都进不去</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([_device isWhiteBalanceModeSupported:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureWhiteBalanceModeAutoWhiteBalance</span>]) { [_device setWhiteBalanceMode:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureWhiteBalanceModeAutoWhiteBalance</span>]; } [_device unlockForConfiguration]; } }</code>
根据前后置位置拿到相应的摄像头:
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;">- (<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevice</span> *)cameraWithPosition:(<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevicePosition</span>)position{ <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSArray</span> *devices = [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevice</span> devicesWithMediaType:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVMediaTypeVideo</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">for</span> ( <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevice</span> *device <span class="hljs-keyword" style="color: rgb(133, 153, 0);">in</span> devices ) <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ( device<span class="hljs-variable" style="color: rgb(181, 137, 0);">.position</span> == position ){ <span class="hljs-keyword" style="color: rgb(133, 153, 0);">return</span> device; } <span class="hljs-keyword" style="color: rgb(133, 153, 0);">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>; }</code>
3、拍照拿到相应图片:
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;">- (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span>)photoBtnDidClick { <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureConnection</span> *conntion = [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.imageOutput</span> connectionWithMediaType:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVMediaTypeVideo</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> (!conntion) { <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSLog</span>(<span class="hljs-string" style="color: rgb(42, 161, 152);">@"拍照失败!"</span>); <span class="hljs-keyword" style="color: rgb(133, 153, 0);">return</span>; } [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.imageOutput</span> captureStillImageAsynchronouslyFromConnection:conntion completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSError</span> *error) { <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> (imageDataSampleBuffer == <span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>) { <span class="hljs-keyword" style="color: rgb(133, 153, 0);">return</span> ; } <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSData</span> *imageData = [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureStillImageOutput</span> jpegStillImage<span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSDataRepresentation</span>:imageDataSampleBuffer]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.image</span> = [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIImage</span> imageWithData:imageData]; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> stopRunning]; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.view</span> addSubview:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.cameraImageView</span>]; }</code>
4、保存照片到相册:
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;"><span class="hljs-preprocessor" style="color: rgb(203, 75, 22);">#pragma - 保存至相册</span> - (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span>)saveImageToPhotoAlbum:(<span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIImage</span>*)savedImage { <span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIImageWriteToSavedPhotosAlbum</span>(savedImage, <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span>, <span class="hljs-keyword" style="color: rgb(133, 153, 0);">@selector</span>(image:didFinishSavingWithError:contextInfo:), <span class="hljs-literal" style="color: rgb(0, 102, 102);">NULL</span>); } <span class="hljs-comment" style="color: rgb(147, 161, 161);">// 指定回调方法</span> - (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span>)image: (<span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIImage</span> *) image didFinishSavingWithError: (<span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSError</span> *) error contextInfo: (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span> *) contextInfo { <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSString</span> *msg = <span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span> ; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span>(error != <span class="hljs-literal" style="color: rgb(0, 102, 102);">NULL</span>){ msg = <span class="hljs-string" style="color: rgb(42, 161, 152);">@"保存图片失败"</span> ; }<span class="hljs-keyword" style="color: rgb(133, 153, 0);">else</span>{ msg = <span class="hljs-string" style="color: rgb(42, 161, 152);">@"保存图片成功"</span> ; } <span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIAlertView</span> *alert = [[<span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIAlertView</span> alloc] initWithTitle:<span class="hljs-string" style="color: rgb(42, 161, 152);">@"保存图片结果提示"</span> message:msg delegate:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span> cancelButtonTitle:<span class="hljs-string" style="color: rgb(42, 161, 152);">@"确定"</span> otherButtonTitles:<span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>]; [alert show]; }</code>
5、前后置摄像头的切换
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;">- (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span>)changeCamera{ <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSUInteger</span> cameraCount = [[<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevice</span> devicesWithMediaType:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVMediaTypeVideo</span>] count]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> (cameraCount > <span class="hljs-number" style="color: rgb(42, 161, 152);">1</span>) { <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSError</span> *error; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//给摄像头的切换添加翻转动画</span> <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CATransition</span> *animation = [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">CATransition</span> animation]; animation<span class="hljs-variable" style="color: rgb(181, 137, 0);">.duration</span> = <span class="hljs-number" style="color: rgb(42, 161, 152);">.5</span>f; animation<span class="hljs-variable" style="color: rgb(181, 137, 0);">.timingFunction</span> = [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">CAMediaTimingFunction</span> functionWithName:k<span class="hljs-built_in" style="color: rgb(38, 139, 210);">CAMediaTimingFunctionEaseInEaseOut</span>]; animation<span class="hljs-variable" style="color: rgb(181, 137, 0);">.type</span> = <span class="hljs-string" style="color: rgb(42, 161, 152);">@"oglFlip"</span>; <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevice</span> *newCamera = <span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>; <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDeviceInput</span> *newInput = <span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//拿到另外一个摄像头位置</span> <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevicePosition</span> position = [[_input device] position]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> (position == <span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevicePositionFront</span>){ newCamera = [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span> cameraWithPosition:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevicePositionBack</span>]; animation<span class="hljs-variable" style="color: rgb(181, 137, 0);">.subtype</span> = k<span class="hljs-built_in" style="color: rgb(38, 139, 210);">CATransitionFromLeft</span>;<span class="hljs-comment" style="color: rgb(147, 161, 161);">//动画翻转方向</span> } <span class="hljs-keyword" style="color: rgb(133, 153, 0);">else</span> { newCamera = [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span> cameraWithPosition:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDevicePositionFront</span>]; animation<span class="hljs-variable" style="color: rgb(181, 137, 0);">.subtype</span> = k<span class="hljs-built_in" style="color: rgb(38, 139, 210);">CATransitionFromRight</span>;<span class="hljs-comment" style="color: rgb(147, 161, 161);">//动画翻转方向</span> } <span class="hljs-comment" style="color: rgb(147, 161, 161);">//生成新的输入</span> newInput = [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureDeviceInput</span> deviceInputWithDevice:newCamera error:<span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>]; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.previewLayer</span> addAnimation:animation forKey:<span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> (newInput != <span class="hljs-literal" style="color: rgb(0, 102, 102);">nil</span>) { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> beginConfiguration]; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> removeInput:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.input</span>]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> canAddInput:newInput]) { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> addInput:newInput]; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.input</span> = newInput; } <span class="hljs-keyword" style="color: rgb(133, 153, 0);">else</span> { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> addInput:<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.input</span>]; } [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.session</span> commitConfiguration]; } <span class="hljs-keyword" style="color: rgb(133, 153, 0);">else</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> (error) { <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSLog</span>(<span class="hljs-string" style="color: rgb(42, 161, 152);">@"toggle carema failed, error = %@"</span>, error); } } }</code>
6、相机的其它参数设置
<code class="objectivec" style="padding: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12px; border: none; background-color: transparent;"><span class="hljs-comment" style="color: rgb(147, 161, 161);">//AVCaptureFlashMode 闪光灯</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//AVCaptureFocusMode 对焦</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//AVCaptureExposureMode 曝光</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//AVCaptureWhiteBalanceMode 白平衡</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//闪光灯和白平衡可以在生成相机时候设置</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//曝光要根据对焦点的光线状况而决定,所以和对焦一块写</span> <span class="hljs-comment" style="color: rgb(147, 161, 161);">//point为点击的位置</span> - (<span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span>)focusAtPoint:(<span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGPoint</span>)point{ <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGSize</span> size = <span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.view</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.bounds</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.size</span>; <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGPoint</span> focusPoint = <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGPointMake</span>( point<span class="hljs-variable" style="color: rgb(181, 137, 0);">.y</span> /size<span class="hljs-variable" style="color: rgb(181, 137, 0);">.height</span> ,<span class="hljs-number" style="color: rgb(42, 161, 152);">1</span>-point<span class="hljs-variable" style="color: rgb(181, 137, 0);">.x</span>/size<span class="hljs-variable" style="color: rgb(181, 137, 0);">.width</span> ); <span class="hljs-built_in" style="color: rgb(38, 139, 210);">NSError</span> *error; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> lockForConfiguration:&error]) { <span class="hljs-comment" style="color: rgb(147, 161, 161);">//对焦模式和对焦点</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> isFocusModeSupported:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureFocusModeAutoFocus</span>]) { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> setFocusPointOfInterest:focusPoint]; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> setFocusMode:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureFocusModeAutoFocus</span>]; } <span class="hljs-comment" style="color: rgb(147, 161, 161);">//曝光模式和曝光点</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span> ([<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> isExposureModeSupported:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureExposureModeAutoExpose</span> ]) { [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> setExposurePointOfInterest:focusPoint]; [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> setExposureMode:<span class="hljs-built_in" style="color: rgb(38, 139, 210);">AVCaptureExposureModeAutoExpose</span>]; } [<span class="hljs-keyword" style="color: rgb(133, 153, 0);">self</span><span class="hljs-variable" style="color: rgb(181, 137, 0);">.device</span> unlockForConfiguration]; <span class="hljs-comment" style="color: rgb(147, 161, 161);">//设置对焦动画</span> _focusView<span class="hljs-variable" style="color: rgb(181, 137, 0);">.center</span> = point; _focusView<span class="hljs-variable" style="color: rgb(181, 137, 0);">.hidden</span> = <span class="hljs-literal" style="color: rgb(0, 102, 102);">NO</span>; [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIView</span> animateWithDuration:<span class="hljs-number" style="color: rgb(42, 161, 152);">0.3</span> animations:^{ _focusView<span class="hljs-variable" style="color: rgb(181, 137, 0);">.transform</span> = <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGAffineTransformMakeScale</span>(<span class="hljs-number" style="color: rgb(42, 161, 152);">1.25</span>, <span class="hljs-number" style="color: rgb(42, 161, 152);">1.25</span>); }completion:^(<span class="hljs-built_in" style="color: rgb(38, 139, 210);">BOOL</span> finished) { [<span class="hljs-built_in" style="color: rgb(38, 139, 210);">UIView</span> animateWithDuration:<span class="hljs-number" style="color: rgb(42, 161, 152);">0.5</span> animations:^{ _focusView<span class="hljs-variable" style="color: rgb(181, 137, 0);">.transform</span> = <span class="hljs-built_in" style="color: rgb(38, 139, 210);">CGAffineTransformIdentity</span>; } completion:^(<span class="hljs-built_in" style="color: rgb(38, 139, 210);">BOOL</span> finished) { _focusView<span class="hljs-variable" style="color: rgb(181, 137, 0);">.hidden</span> = <span class="hljs-literal" style="color: rgb(0, 102, 102);">YES</span>; }]; }]; } }</code>
7、遇到的一些坑和解决办法
1) 前后置摄像头的切换
前后值不能切换,各种尝试找了半天没找到有原因。后来发现我在设置图片尺寸的时候设置为1080P [self.session canSetSessionPreset: AVCaptureSessionPreset1920x1080] ,前置摄像头并不支持这么大的尺寸,所以就不能切换前置摄像头。我验证了下 前置摄像头最高支持720P,720P以内可自由切换。 当然也可以在前后置摄像头切换的时候,根据前后摄像头来设置不同的尺寸,这里不在赘述。
2)焦点位置
CGPoint focusPoint = CGPointMake( point.y /size.height ,1-point.x/size.width );
setExposurePointOfInterest:focusPoint 函数后面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,后设置对焦位置,就会导致很奇怪的现象,对焦位置是你上次点击的位置。所以一定要先设置位置,再设置对焦模式。
曝光同上
8、写在最后
附上demo:https://github.com/nanshanyi/photographDemo
常用到的基本就这么多,写的并不完善,有什么不对的,欢迎大家批评指正,共同学习。