做英文网站 赚美元,网络营销促销策略有哪些,太原医疗网站建设,中山专业做网站公司引言
在项目开发中#xff0c;从媒体库中选择图片或使用相机拍摄图片是一个极为普遍的需求。通常#xff0c;我们使用UIImagePickerController来实现单张图片选择或启动相机拍照。整个拍照过程由UIImagePickerController内部实现#xff0c;无需我们关心细节#xff0c;只…引言
在项目开发中从媒体库中选择图片或使用相机拍摄图片是一个极为普遍的需求。通常我们使用UIImagePickerController来实现单张图片选择或启动相机拍照。整个拍照过程由UIImagePickerController内部实现无需我们关心细节只需实现相应的回调以获取所需的图片。
然而你或许好奇拍照的底层实现是什么样的是否能够自己调用手机摄像头完成拍照功能这正是AVFoundation发挥作用的地方。AVFoundation是一个强大的框架提供了访问音视频的底层功能包括相机和麦克风。通过AVFoundation我们能够直接与设备的摄像头进行交互实现自定义的拍照功能为我们提供更大的灵活性和控制权。
在接下来的内容中我们将深入探讨AVFoundation的拍照功能了解如何通过这一框架自定义拍照过程从而更好地满足项目的需求。
介绍 媒体捕捉主要类 首先介绍一下主要类
AVCaptureDevice捕捉设备。相对手机而言它是摄像头麦克风等物理设备定义了一个接口。
AVCaptureDeviceInput捕捉设备的输入。捕捉设备不能直接添加到会话中需要封装在AVCaptureDeviceInput中再进行添加。
AVCaptureSession捕捉会话。捕获会话是整个功能的核心有用链接输入和输出配置捕捉环境。
AVCaptureOutput捕捉的输出。AVCaptureOutput是一个抽象类用于捕捉到的数据进行输出不能直接使用通常我们是使用它的子类比如AVCapturePhotoOutputAVCaptureMovieFileOutput等等。
另外还有一个比较重要的类AVCaptureVideoPreviewLayer它提供了画面的预览功能。
基本使用
这里面演示一下我们使用的最小单元也就是一个拍照功能的最核心代码
创建会话
AVCaptureSession * session [[AVCaptureSession alloc] init];
创建捕捉及输入并添加到会话
AVCaptureDevice * cameraDevice [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError * error;
AVCaptureDeviceInput * cameraInput [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:error];
if ([session canAddInput:cameraInput]) {[session addInput:cameraInput];
}
创建输出并添加到会话
AVCapturePhotoOutput * photoOutput [[AVCapturePhotoOutput alloc] init];
if ([session canAddOutput:photoOutput]) {[session addOutput:photoOutput];
}
上面的代码创建了一个拍摄图片最基础的框架。创建会话将设备捕捉到的数据添加到会话再将数据进行输出静态图片。启动会话视频数据流就可以开始传输了。真正使用起来会比上面的示例代码复杂一点但核心内容仍然是这几个步骤。
完整示例
这一部分内容比较多为了更容易理解我们将对应的功能分散到不同的类中。
PHCameraController捕捉核心类。负责启动会话处理输入和输出。
PHPreviewView预览图层。负责渲染预览画面。
而我们首先把注意力集中在PHCameraController上面。
捕捉核心类
配置会话
我们先来定义一个最小的功能只声明一些拍照所需要的属性及方法。.h中对外暴漏的属性和接口如下
#import Foundation/Foundation.h
#import AVFoundation/AVFoundation.h
NS_ASSUME_NONNULL_BEGINinterface PHCameraController : NSObjectproperty(nonatomic,strong,readonly)AVCaptureSession * captureSession;///设置会话
- (BOOL)setupSession:(NSError **)error;
///开始会话
- (void)startSession;
///停止会话
- (void)stopSession;///拍照
- (void)capturePhoto;
end
NS_ASSUME_NONNULL_END
我们只定义了最基本的功能设置会话启动会话停止会话和拍照。
接下来我们来看一下它的.m文件中的内容。
首先是扩展中的私有属性
#import PHCameraController.h
interface PHCameraController ()AVCapturePhotoCaptureDelegate
///会话启动队列
property(nonatomic,strong)dispatch_queue_t videoQueue;
///会话
property(nonatomic,strong)AVCaptureSession * captureSession;
///图片输出
property(nonatomic,strong)AVCapturePhotoOutput * photoOutput;end
在这里定义了一个自定义的队列一个会话session和AVCaptureOutput的子类AVCapturePhotoOutput专门用于输出静态图片。
再看一下它的接口实现首先是配置会话相关的代码
implementation PHCameraController
- (BOOL)setupSession:(NSError *__autoreleasing _Nullable *)error{self.captureSession [[AVCaptureSession alloc] init];self.captureSession.sessionPreset AVCaptureSessionPresetHigh;//获取默认摄像头AVCaptureDevice * videoDevice [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];AVCaptureDeviceInput * videoInput [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];if (videoInput) {if ([self.captureSession canAddInput:videoInput]) {[self.captureSession addInput:videoInput];self.activeVideoInput videoInput;}}else{return NO;}//设置图片输出self.photoOutput [[AVCapturePhotoOutput alloc] init];NSDictionary * setDic {AVVideoCodecKey:AVVideoCodecTypeJPEG};AVCapturePhotoSettings * settings [AVCapturePhotoSettings photoSettingsWithFormat:setDic];[self.photoOutput capturePhotoWithSettings:settings delegate:self];if ([self.captureSession canAddOutput:self.photoOutput]) {[self.captureSession addOutput:self.photoOutput];}self.videoQueue dispatch_queue_create(com.panghu.VideoQueue, NULL);return YES;
}
end
这和上面提到的最核心的代码实现几乎一致创建会话添加会话输入和输出。
启动会话
再进行捕捉之前需要先启动会话也就是让会话处于准备捕捉静态图片的状态。
相关代码试下如下
- (void)startSession{if (![self.captureSession isRunning]) {dispatch_async(self.videoQueue, ^{[self.captureSession startRunning];});}
}
开始捕捉静态图片
会话启动之后我们就可以调用捕捉图片的方法来进行图片的捕捉
- (void)capturePhoto{NSDictionary * setDic {AVVideoCodecKey:AVVideoCodecTypeJPEG};AVCapturePhotoSettings * settings [AVCapturePhotoSettings photoSettingsWithFormat:setDic];self.photoSettings settings;[self.photoOutput capturePhotoWithSettings:self.photoSettings delegate:self];
}
开始捕捉前我们可以自定义捕捉静态图片的一些配置参数比如
AVVideoCodecKey图片类型。
AVVideoPixelAspectRatioKey像素宽高比。
AVVideoCompressionPropertiesKey压缩属性。
AVVideoWidthKey宽。
AVVideoHeightKey高。
调用拍照方法后会回调AVCapturePhotoCaptureDelegate中的代理方法
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error{NSData * data photo.fileDataRepresentation;UIImage * image [UIImage imageWithData:data];
}
其中image即是我们想要的静态图片。
结束会话
使用完该功能后退出拍照功能需要停止会话
- (void)stopSession{if ([self.captureSession isRunning]) {dispatch_async(self.videoQueue, ^{[self.captureSession stopRunning];});}
}
画面预览类
我们在这里定义一个专门用作画面预览的视图PHPreviewView。
可以在对应的实例中创建一个AVCaptureVideoPreviewLayer用来渲染预览画面也可以用另外一种更优雅的方式通过重写LayerClass方法返回一个AVCaptureVideoPreviewLayer。
.h中的代码如下
interface PHPreviewView : UIView
property(nonatomic,strong)AVCaptureSession * session;
end
只有一个捕捉会话对象。
.m中的实现如下
#import PHPreviewView.h
implementation PHPreviewView(Class)layerClass{return [AVCaptureVideoPreviewLayer class];
}
- (void)setSession:(AVCaptureSession *)session{[(AVCaptureVideoPreviewLayer*)self.layer setSession:session];
}
- (AVCaptureSession *)session{return [(AVCaptureVideoPreviewLayer*)self.layer session];
}
end
通过重写session的set方法来将预览图层与捕捉会话相关联。
通过重写session的get方法来返回捕捉会话。
使用
在视图控制器ViewController中使用拍照功能。
首先声明捕捉的核心类及画面预览类
interface ViewController ()//画面预览view
property(nonatomic,strong)PHPreviewView * previewView;
///相机控制
property(nonatomic,strong)PHCameraController * controller;end
添加画面预览视图
- (void)viewDidLoad {[super viewDidLoad];[self setupView];
}- (void)setupView{[self addPreviewView];[self configController];
}//MARK:画面预览view
- (void)addPreviewView{self.previewView [[PHPreviewView alloc] initWithFrame:self.view.bounds];[self.view addSubview: self.previewView];
}//MARK:配置相机控制器
- (void)configController{self.controller [[PHCameraController alloc] init];NSError * error nil;BOOL isSuccess [self.controller setupSession:error];if (isSuccess) {[self.previewView setSession:self.controller.captureSession];[self.controller startSession];}
}
接下来我们只需要在屏幕上添加一个按钮然后调用拍照方法即可完成静态图片的拍摄
//MARK:拍照或录制
- (void)capture:(UIButton *)sender{[self.controller capturePhoto];
}
结语
在实现自定义拍照功能时除了深入了解AVCapturePhotoSettings等相关设置外我们还需关注一系列前置和后续操作以确保用户体验和功能完整性。
首先我们必须在应用中请求摄像头和麦克风的权限确保用户授权后才能正常使用这些设备。这是保护用户隐私的重要步骤也是提供良好用户体验的前提。
另外在成功捕获照片后处理后续操作也至关重要。使用Photos框架将照片存储到相册以确保用户可以轻松地查看和分享他们的作品。这是一个贴近用户习惯的操作增强了应用的实用性和友好性。
在整个拍照过程中我们还有许多机会进行细致的自定义例如实现自动聚焦、调整曝光、切换摄像头、开启闪光灯等功能。这些细节的处理不仅提升了用户体验也使应用更具吸引力。
在开发过程中不断探索和尝试这些功能根据具体项目需求进行定制将为用户带来更为出色的拍摄体验。通过充分利用AVFoundation的强大功能我们能够打造出更具创意和个性化的拍照应用满足不同用户的期望和需求。