iOS 从相机/相册获取图片的文章很多,本文也并没有对系统的相册/相机界面做多少优化.只是从程序健壮性,用户体验的角度对我以往的代码进行封装优化
首先,demo地址:https://github.com/sun6762/getPicture.git
准备工作
a. 要能使真机在使用时成功调用相册/拍照功能必须在info.plist,添加
Privacy - Camera Usage Description & Privacy - Photo Library Usage Description,当然,在测试的时候根据提示添加更好
b. 要使用imgPickerController的代理必须有UIImagePickerControllerDelegate, UINavigationControllerDelegate2个代理
@interface ViewController ()<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@end
用户开启相机权限
// 引入以下2个类
#import <AVFoundation/AVCaptureDevice.h>
#import <AVFoundation/AVMediaFormat.h>
AVAuthorizationStatus avStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
// avStatus 的4中类型
/*
AVAuthorizationStatusNotDetermined // 初次调用
AVAuthorizationStatusRestricted // 禁用
AVAuthorizationStatusDenied //
AVAuthorizationStatusAuthorized // 开通权限
*/
// 用户开放相机权限后 判断相机是否可用
BOOL useable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
用户开启相册权限,跟上述过程相似
// 导入此类
#import <Photos/Photos.h>
PHAuthorizationStatus phStatus = [PHPhotoLibrary authorizationStatus];
// 同样 phStatus 有4中类型
/*
PHAuthorizationStatusNotDetermined = 0
PHAuthorizationStatusRestricted
PHAuthorizationStatusDenied
PHAuthorizationStatusAuthorized
*/
// 判断相册权限
[UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]
打开相机/相册
// 打开相机/相册
- (void)openSuccWith:(NSString *)flag{
UIImagePickerController *photoPicker = [UIImagePickerController new];
photoPicker.delegate = self;
photoPicker.allowsEditing = NO;
if ([flag isEqualToString:AV]) {
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
if ([flag isEqualToString:PH]) {
photoPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[self presentViewController:photoPicker animated:YES completion:nil];
}
用户关闭iOS拍照/相册权限,引导用户打开拍照/相册权限
- (void)guideUserOpenAuth{
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"请打开访问权限" preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:nil];
UIAlertAction *act = [UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// 引导用户设置
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
}];
[alertC addAction:alertA];
[alertC addAction:act];
[self presentViewController:alertC animated:YES completion:nil];
}
UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
NSString *mediaType=[info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:@"public.image"]) {
UIImage * image;
// 判断,图片是否允许修改
if ([picker allowsEditing]){
//获取用户编辑之后的图像
image = [info objectForKey:UIImagePickerControllerEditedImage];
} else {
// 照片的元数据参数
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
// 压缩图片
UIImage *compressImg = [self compressPictureWith:image];
self.imgView.image = compressImg;
// NSLog(@"%@",NSStringFromCGSize(compressImg.size));
// 用于上传
NSData *tmpData = UIImageJPEGRepresentation(compressImg, 0.5);
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:nil];
}
我们获取的图片上传到服务器,都需要图片压缩,这也有,是不是很贴心
/ 压缩图片
- (UIImage *)compressPictureWith:(UIImage *)originnalImage{
CGFloat ruleWidth = 600;
if (originnalImage.size.width < ruleWidth) {
return originnalImage;
}
CGFloat hight = ruleWidth/originnalImage.size.width * originnalImage.size.height;
CGRect rect = CGRectMake(0, 0, ruleWidth, hight);
// 开启图片上下文
UIGraphicsBeginImageContext(rect.size);
// 将图片渲染到图片上下文
[originnalImage drawInRect:rect];
// 获取图片
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图片上下文
UIGraphicsEndImageContext();
return img;
}
....
以后有时间再将打开界面优化一下