基于 UIImagePickerController 的拓展,分别支持调用相机、相册的功能,其中相机可以设置默认调用前后摄像头;

简单对此进行了封装和实现,其中还有很多点可以继续挖掘和优化,该版本具体 code 如下:

GitHub 链接地址

声明:

/*
相机管理
*/ #import <Foundation/Foundation.h> @protocol YHCameraManagerDelegate <NSObject> /** 事件回调*/
- (void)YHCameraCallBack:(UIImage *)image; @end @interface YHCameraManager : NSObject @property (nonatomic, assign) id <YHCameraManagerDelegate> delegate; /** 单例对象*/
+ (instancetype)shareInstance; /**
调用相机或相册 @param deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller 当前 VC 控件
*/
- (void)openCameraOrPhotoLibraryWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller; /**
调用相机拍照 @param deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller 当前 VC 控件
*/
- (void)openCameraWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller; /**
调用相机拍摄
@param deviceType deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller controller 当前 VC 控件
*/
- (void)openCameraVideoWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller; /**
调用相册
@param controller 当前 VC 控件
*/
- (void)openPhotoLibraryWithController:(UIViewController *)controller; @end

  

实现:

#import "YHCameraManager.h"
#import <AssetsLibrary/AssetsLibrary.h>// 资源库 @interface YHCameraManager () <UIImagePickerControllerDelegate,UINavigationControllerDelegate> @end @implementation YHCameraManager #pragma mark - ****************************** Base
+ (instancetype)shareInstance {
static YHCameraManager *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[YHCameraManager alloc] init];
}); return singleton;
} #pragma mark - ****************************** Interface methods
/**
调用相机或相册(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param deviceType 摄像头设备类型
@param controller 当前 VC 控件
*/
- (void)openCameraOrPhotoLibraryWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller {
UIAlertController *alertCon = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet]; kWeakSelf(self);
[alertCon addAction:[UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [weakself openCameraWithCameraDeviceType:deviceType AndController:controller]; }]];
[alertCon addAction:[UIAlertAction actionWithTitle:@"从相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[weakself openPhotoLibraryWithController:controller]; }]]; [alertCon addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]]; [controller presentViewController:alertCon animated:YES completion:^{ }];
} /**
调用相机拍照(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param deviceType 摄像头设备类型
@param controller 当前 VC 控件
*/
- (void)openCameraWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller {
// 判断是否可以打开照相机
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController *pickerCon = [[UIImagePickerController alloc] init];
pickerCon.delegate = self;
pickerCon.allowsEditing = YES;// 设置拍摄的照片是否允许编辑 // 摄像头
pickerCon.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerCon.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;// 设置拍照类型(拍照 & 摄像)
if ([deviceType isEqualToString:@"Front"]) {// 设置使用手机摄像头类型
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceFront;// 设置使用手机前置摄像头
}
else {
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceRear;// 设置使用手机后置摄像头
} [controller presentViewController:pickerCon animated:YES completion:^{
NSLog(@"调用了 --- 摄像头");
}];
}
else {
[MBProgressHUD showCommonHudWithAlertString:@"没有摄像头" afterDelay:2.0 toView:controller.view];
}
} /**
调用相机拍摄 @param deviceType deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller controller 当前 VC 控件
*/
- (void)openCameraVideoWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller {
// 判断是否可以打开照相机
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController *pickerCon = [[UIImagePickerController alloc] init];
pickerCon.delegate = self;
pickerCon.allowsEditing = YES;// 设置拍摄的照片是否允许编辑 // 摄像头
pickerCon.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerCon.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];// 将 mediaType 设置为所有支持的媒体类型
pickerCon.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;// 设置拍照类型(拍照 & 摄像)
pickerCon.videoQuality = UIImagePickerControllerQualityTypeHigh;// 设置拍摄视频的清晰度
if ([deviceType isEqualToString:@"Front"]) {// 设置使用手机摄像头类型
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceFront;// 设置使用手机前置摄像头
}
else {
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceRear;// 设置使用手机后置摄像头
} [controller presentViewController:pickerCon animated:YES completion:^{
NSLog(@"调用了 --- 摄像头");
}];
}
else {
[MBProgressHUD showCommonHudWithAlertString:@"没有摄像头" afterDelay:2.0 toView:controller.view];
}
} /**
调用相册 @param controller 当前 VC 控件
*/
- (void)openPhotoLibraryWithController:(UIViewController *)controller {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self; [controller presentViewController:imagePicker animated:YES completion:^{
NSLog(@"调用了 --- 相册");
}];
}
else {
[MBProgressHUD showCommonHudWithAlertString:@"无法打开相册" afterDelay:2.0 toView:controller.view];
}
} #pragma mark - UIImagePickerControllerDelegate
/**
拍照完成回调
@param picker 控件
@param info 数据
*/
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
NSLog(@"UIImagePickerControllerDelegate --- FinishPickingMedia"); // 获取拍摄数据的类型(照片 or 视频)
// NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; if (picker.sourceType == UIImagePickerControllerSourceTypeCamera || picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {// 图片 [mediaType isEqualToString:(NSString *)kUTTypeImage]
UIImage *theImg = nil;
if ([picker allowsEditing]) {// 判断图片是否允许修改
// 获取用户编辑之后的图像
theImg = [info objectForKey:UIImagePickerControllerEditedImage];
}
else {// 获取原图
theImg = [info objectForKey:UIImagePickerControllerOriginalImage];
} // 保存图片至相册中
UIImageWriteToSavedPhotosAlbum(theImg, self, nil, nil); // 图片后续处理相关
if ([self.delegate respondsToSelector:@selector(YHCameraCallBack:)]) {
[self.delegate YHCameraCallBack:theImg];
}
}
else {// 视频
// 获取视频文件 url
NSURL *urlMedia = [info objectForKey:UIImagePickerControllerMediaType];
// 创建 ALAssetsLibrary 对象并将视频保存到媒体库
ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
// 将视频保存至相册
[assetsLib writeVideoAtPathToSavedPhotosAlbum:urlMedia completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"视频拍摄 --- 写入失败:%@", error);
}
else {
NSLog(@"视频拍摄 --- 写入成功");
}
}];
} [picker dismissViewControllerAnimated:YES completion:^{ }];
} /**
拍照页面取消选择的时候,调用该方法
@param picker 当前控件
*/
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:^{ }];
} @end

  

以上便是此次的分析内容,还望大神多多指教!

最新文章

  1. freeswitch注册过程分析
  2. nginx + SSL优化配置
  3. 为Docker容器配置固定IP
  4. 常见S1信令交互流程
  5. 从点亮一个LED开始,Cortex-A9裸机程序设计
  6. OC和C语言的混编注意点和好处
  7. Storing and Retrieving Images from SQL Server using Microsoft .NET
  8. 先对数组排序,在进行折半查找(C++)
  9. unity3d使用litjson中文显示的问题
  10. 【卷二】网络二—TCP服务器与客户端
  11. MySQ安装
  12. 用java来实现验证码功能(本帖为转载贴),作为个人学习收藏用
  13. Linux iostat 命令
  14. 区间DP,数位DP
  15. 软件工程第4次作业------石墨文档Android客户端案例分析
  16. 【redis专题(4)】命令语法介绍之sorted_set
  17. jq设置控件可用不可用
  18. 机器学习初入门02 - Pandas的基本操作
  19. JY播放器【喜马拉雅FM电脑端,附带下载功能】
  20. 2016级算法第二次上机-E.AlvinZH的儿时梦想——运动员篇

热门文章

  1. Android DataBinding实现地址三联动
  2. Vue表格中,对数据进行转换、处理
  3. HihoCoder#1279 : Rikka with Sequence(dp 枚举子集 二进制 神仙题)
  4. angularjs如何默认选中radio
  5. Pairwise ranking methods: RankNet与LambdaRank
  6. SVNKit学习——使用High-Level API管理Working Copy示例(六)
  7. pdf2swf 转换时报错。This file is too complex to render- SWF only supports 65536 shapes at once
  8. 【NLP_Stanford课堂】分词
  9. Consul 配置ACLs
  10. Java Hotspot client模式和server模式的区别