这篇文章主要为大家详细介绍了ios自定义相机功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
大多数应用都会涉及到上传照片这个功能,图片来源无非是从相册获取或者相机拍摄。如果不是特别要求,调用系统已经满足需求。但对于特殊需求,就需要自定义相机拍摄界面了。
对于无需定制的相机,使用系统的UIKit库里的UIImagePickerController类,几行代码,几个代理方法就可满足所需。但如果要深度定制,就要系统库AVFoundation内部的相关类。
创建自己的相机管理类CameraManager(继承于n对象)。h文件
#导入foundation/基金会. h
#导入AVFoundation/AVFoundation.h
//拍照后的回调,传递拍摄的照片
泰伯迪void(^didcapturephotoblock)(uiimage *静态图像);
@ interface PXCameraManager:ns对象
@property (nonatomic,h3)AVCaptureSession * session;//AVCaptureSession对象来执行输入设备和输出设备之间的数据传递
@property (nonatomic,h3)AVCaptureVideoPreviewLayer *预览层;//预览图层,来显示照相机拍摄到的画面
@property (nonatomic,h3)AVCaptureDeviceInput *设备输入;//AVCaptureDeviceInput对象是输入流
@property (nonatomic,h3)AVCaptureStillImageOutput * stillImageOutput;//照片输出流对象
@property (nonatomic,assign)CGRect previewLayerFrame;//拍照区域
/* 为其他类提供的自定义接口*/
//设置拍照区域(其中目标视图为要展示拍照界面的查看)
-(void)configureWithtargetViewLayer:(ui view *)目标视图预览rect:(CG rect)preivewRect;
//拍照成功回调
-(void)拍照:(DidCapturePhotoBlock)block;
//添加/移除相机浮层(如果有需求要在相机拍照区域添加浮层的时候使用)
-(void)addCoverImageWithImage:(ui image *)image;
-(void)removeCoverImageWithImage:(ui image *)image;
//前后摄像头切换
-(无效)开关摄像机;
//闪光灯切换
-(void)configCameraFlashlight;
@end。m文件
@property(非原子,强)UIView * preview//展现拍照区域的视角
@property(非原子,强)ui imageview * cover imageview//拍照区域浮层
@property (nonatomic,assign)BOOL isCaremaBack;
@property (nonatomic,assign)avcaptureflash模式flash模式;
//初始化的时候设置自己想要的默认属性
-(实例类型)初始化{
self=[super init];
如果(自己){
self.isCaremaBack=YES//默认后置摄像头
自我。flashmode=AVCaptureFlashModeAuto;//默认自动闪光灯
}
回归自我;
}
实现接口的方法
1、准备相关硬件
-(void)configureWithTargetViewLayer:(ui view *)目标视图预览rect:(CGRect)preivewRect {
self.preview=targetView
//开始一些相机相关硬件配置
[自行添加会话];//创建会议
[self addVideoPreviewLayerWithRect:preivewRect];//用会议创建创建层
【self addvideinputbackcamera:self。iscaremaback】;//给会议配置摄像头
【self addVideoFlashlightWithFlashModel:self。flash mode】;//配置闪光灯
[self addStillImageOutput];//给会议配置输出
}
2、拍照
#杂注标记-
-(无效)拍照:(DidCapturePhotoBlock)block{
AVCaptureConnection * captureConnection=[self findCaptureConnection];
[captureConnection setVideoScaleAndCropFactor:1.0f];
[_ still image output capturestillimageasynchronouslyfromconnection:captureconnection completionhandler:^(cmsamplebufferref图像数据样本缓冲区,NSError *error) {
ns data * imageData=[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
ui image * image=[ui image imageWithData:image data];
//这里可以根据不同需求对拍摄到的照片做一些压缩或者裁剪的处理,这里我就偷懒不弄了。
如果(阻止){
块(图像);
}
}];
}
3、切换摄像头
-(无效)开关摄像机{
如果(!_设备输入){
返回;
}
[_ session开始配置];
[_ session删除输入:_设备输入];
self.isCaremaBack=!self.isCaremaBack
【self addvideinputbackcamera:self。iscaremaback】;
[_会话提交配置];
}
4、切换闪光灯
- (void)configCameraFlashlight{
开关(self.flashMode) {
案例AVCaptureFlashModeAuto:
{
自我。flashmode=AVCaptureFlashModeOff;
}
打破;
案例AVCaptureFlashModeOff:
{
自我。flashmode=AVCaptureFlashModeOn;
}
打破;
案例AVCaptureFlashModeOn:
{
自我。flashmode=AVCaptureFlashModeAuto;
}
打破;
默认值:
打破;
}
【self addVideoFlashlightWithFlashModel:self。flash mode】;
}
添加/移除浮层
-(void)addCoverImageWithImage:(ui image *)image {
_封面图像视图。image=图像;
}
-(void)removeCoverImageWithImage:(ui image *)image {
_封面图像视图。image=nil
}
下面是配置硬件里的几个方法实现
-(无效)添加会话{
如果(!self.session) {
AVCaptureSession * session=[[AVCaptureSession alloc]init];
self.session=session
}
}
-(void)addVideoPreviewLayerWithRect:(CGRect)preview rect {
如果(!自我。预览播放器){
AVCaptureVideoPreviewLayer * preview layer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:_ session];
预览图层。视频重力=AVLayerVideoGravityResizeAspectFill;
自我。预览层=预览层;
【自我。预览。层添加子层:自我。预览层];
}
自我。预览图层。frame=预览矩形;
}
-(void)addvideinputbackcamera:(BOOL)back {
NSArray * devices=[AVCaptureDevice设备];
AVCaptureDevice *前置摄像头;
AVCaptureDevice *背景摄像机
//获取前、后摄像头
对于(AVCaptureDevice *设备中的设备){
如果([设备hasMediaType:AVMediaTypeVideo]){
如果([设备位置]==AVCaptureDevicePositionBack){
backCamera=设备;
} else if([设备位置]==AVCaptureDevicePositionFront){
前置摄像头=设备;
}
}
}
NSError * error=零
如果(返回){
AVCaptureDeviceInput * backCameraDeviceInput=[avcapturedeviceinputdevice:back camera error:error];
如果(!错误){
if([_ session canadin input:backCameraDeviceInput]){
[_ session add input:backCameraDeviceInput];
自我。设备输入=backCameraDeviceInput
}否则{
NSLog(@ 出错啦);
}
}
}否则{
AVCaptureDeviceInput *前置摄像头设备输入=[avcapturedeviceinputdeviceinputtwithdevice:前置摄像头错误:错误];
如果(!错误){
if([_ session canadin input:frontCameraDeviceInput]){
[_ session add input:frontCameraDeviceInput];
自我。设备输入=frontCameraDeviceInput
}否则{
NSLog(@ 出错啦);
}
}
}
}
-(void)addVideoFlashlightWithFlashModel:(AVCaptureFlashMode)flashmode {
AVCaptureDevice * device=[AVCaptureDevice defaultdevicewithmediatetype:AVMediaTypeVideo];
[配置的设备锁定:无];
如果([设备有闪存]) {
设备。flashmode=self。flashmode
}
[设备解锁以进行配置];
}
- (void)addStillImageOutput{
如果(!self.stillImageOutput) {
AVCaptureStillImageOutput * stillImageOutput=[[AVCaptureStillImageOutput alloc]init];
ns dictionary * outPutSettingDict=[[ns dictionary alloc]initWithObjectsAndKeys:avvideocodecjpge,AVVideoCodecKey,nil];
静态图像输出。输出设置=outPutSettingDict
[_ session add output:stillImageOutput];
自我。stillImageOutput=stillImageOutput;
}
}
-(AVCaptureConnection *)findCaptureConnection {
AVCaptureConnection *视频连接;
for(AVCaptureConnection * connection in _ stillimageoutput。连接){
对于(连接中的AVCaptureInputPort *端口。输入端口){
如果([[端口媒体类型] isEqual:AVMediaTypeVideo]) {
视频连接=连接;
返回视频连接;
}
}
}
返回无
}
到此,一个自定义相机的类就有了,要使用的时候,尽管调用吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。