iOS 系统- 相册与 拍照
2020-02-22 本文已影响0人
奔跑吧小蚂蚁
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface SystemImagePickerManager : NSObject
/// 创建这样一个管理类对象
- (instancetype)initWithViewController:(UIViewController *)VC;
///选择图片的回调block
@property (nonatomic,copy) void(^didSelectImageBlock) (UIImage *image);
/// 相册选择器对象
@property (nonatomic,strong) UIImagePickerController *imagePicker;
///最大视频时长
@property (nonatomic,assign) NSTimeInterval videoMaximumDuration;
//是否支持视屏选择
@property (nonatomic,assign) BOOL isVideo;
@property (nonatomic,assign) BOOL allowsEditing;
///快速创建一个图片选择弹出窗
- (void)quickAlertSheetPickerImage ;
///打开相机
- (void)openCamera;
///打开相册
- (void)openPhotoLibrary ;
@end
NS_ASSUME_NONNULL_END
#import "SystemImagePickerManager.h"
@interface SystemImagePickerManager ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIActionSheetDelegate>
///来源控制器
@property (nonatomic,strong) UIViewController *orginViewController;
/// 取出的图片
@property (nonatomic,strong) UIImage *tempImage;
@end
@implementation SystemImagePickerManager
- (UIImagePickerController *)imagePicker{
if (!_imagePicker) {
_imagePicker = [[UIImagePickerController alloc] init];
_imagePicker.delegate = self;
/// 转场动画方式
// _imagePicker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
_imagePicker.allowsEditing = YES; //允许编辑
_imagePicker.videoMaximumDuration = 15 ; //视频时长默认15s
_imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh;
}
return _imagePicker;
}
- (void)setAllowsEditing:(BOOL)allowsEditing {
_allowsEditing = allowsEditing;
self.imagePicker.allowsEditing = allowsEditing; //允许编辑
}
- (void)setIsVideo:(BOOL)isVideo{
_isVideo = isVideo;
if (isVideo == YES) {
/// 媒体类型
self.imagePicker.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypeMovie];
}else{
/// 媒体类型
self.imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
}
}
- (instancetype)initWithViewController:(UIViewController *)VC{
self = [super init];
if (self) {
self.orginViewController = VC;
}
return self;
}
#pragma mark- 快速创建一个图片选择弹出窗
- (void)quickAlertSheetPickerImage{
UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *takePhotoAction = [UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self openCamera];
}];
[alertVc addAction:takePhotoAction];
UIAlertAction *imagePickerAction = [UIAlertAction actionWithTitle:@"去相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self openPhotoLibrary];
}];
[alertVc addAction:imagePickerAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
[alertVc addAction:cancelAction];
[self.orginViewController presentViewController:alertVc animated:YES completion:nil];
}
- (void)openCamera {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"未获得授权使用相机,请在iOS\"设置中\"-\"隐私\"-\"相机\"中打开" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *conform = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:conform];
[self.orginViewController presentViewController:alert animated:YES completion:nil];
return;
} else if (authStatus == AVAuthorizationStatusNotDetermined) {
// fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[self openCamera];
});
}
}];
}
else {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self.orginViewController presentViewController:self.imagePicker animated:YES completion:nil];
}
}
- (void)openPhotoLibrary {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
switch (status) {
case PHAuthorizationStatusAuthorized: //已获取权限
{
[[UIBarButtonItem appearance] setTintColor:[UIColor blackColor]];
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
[self.orginViewController presentViewController:self.imagePicker animated:YES completion:nil];
}
break;
case PHAuthorizationStatusDenied: //用户已经明确否认了这一照片数据的应用程序访问
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"未获得授权使用相机,请在iOS\"设置中\"-\"隐私\"-\"相册\"中打开" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *conform = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:conform];
[self.orginViewController presentViewController:alert animated:YES completion:nil];
return ;
}
break;
case PHAuthorizationStatusRestricted://此应用程序没有被授权访问的照片数据。可能是家长控制权限
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"未获得授权使用相机,请在iOS\"设置中\"-\"隐私\"-\"相册\"中打开" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *conform = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:conform];
[self.orginViewController presentViewController:alert animated:YES completion:nil];
return ;
}
break;
default:
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"访问相册失败" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *conform = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:conform];
[self.orginViewController presentViewController:alert animated:YES completion:nil];
return;
}
break;
}
});
}];
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
[[UIBarButtonItem appearance] setTintColor:nil];
if (self.allowsEditing) {
UIImage *orginImage = info[UIImagePickerControllerEditedImage];
self.tempImage = [self fixOrientation:orginImage];
} else {
UIImage *orginImage = info[UIImagePickerControllerOriginalImage];
self.tempImage = [self fixOrientation:orginImage];
}
/// 选择的图片
if(self.didSelectImageBlock){
self.didSelectImageBlock(self.tempImage);
}
///拍到的照片顺带保存到相册
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
[self saveImageToSystemPhotosAlbum];
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[[UIBarButtonItem appearance] setTintColor:nil];
[self.imagePicker dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark- 拍的照片保存到系统相册
- (void)saveImageToSystemPhotosAlbum{
UIImageWriteToSavedPhotosAlbum(self.tempImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
/// 系统指定的回调方法
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
NSString *msg = nil ;
if(error != NULL){
msg = @"保存图片失败" ;
}else{
msg = @"保存图片成功" ;
}
NSLog(@"%@",msg);
}
///矫正图片方向
- (UIImage*)fixOrientation:(UIImage*)aImage
{
// No-op if the orientation is already correct
if (aImage.imageOrientation == UIImageOrientationUp)
return aImage;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (aImage.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
default:
break;
}
switch (aImage.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
default:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
CGImageGetBitsPerComponent(aImage.CGImage), 0,
CGImageGetColorSpace(aImage.CGImage),
CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (aImage.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.height, aImage.size.width), aImage.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.width, aImage.size.height), aImage.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage* img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}