#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface SystemImagePickerManager : NSObject
/// 創(chuàng)建這樣一個管理類對象
- (instancetype)initWithViewController:(UIViewController *)VC;
///選擇圖片的回調(diào)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;
///快速創(chuàng)建一個圖片選擇彈出窗
- (void)quickAlertSheetPickerImage ;
///打開相機(jī)
- (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;
/// 轉(zhuǎn)場動畫方式
// _imagePicker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
_imagePicker.allowsEditing = YES; //允許編輯
_imagePicker.videoMaximumDuration = 15 ; //視頻時長默認(rèn)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- 快速創(chuàng)建一個圖片選擇彈出窗
- (void)quickAlertSheetPickerImage{
UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *takePhotoAction = [UIAlertAction actionWithTitle:@"相機(jī)" 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:@"未獲得授權(quán)使用相機(jī),請在iOS\"設(shè)置中\(zhòng)"-\"隱私\"-\"相機(jī)\"中打開" 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, 防止用戶首次拍照拒絕授權(quán)時相機(jī)頁黑屏
[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: //已獲取權(quán)限
{
[[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: //用戶已經(jīng)明確否認(rèn)了這一照片數(shù)據(jù)的應(yīng)用程序訪問
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"未獲得授權(quán)使用相機(jī),請在iOS\"設(shè)置中\(zhòng)"-\"隱私\"-\"相冊\"中打開" 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://此應(yīng)用程序沒有被授權(quán)訪問的照片數(shù)據(jù)耙册∷貉郑可能是家長控制權(quán)限
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"未獲得授權(quán)使用相機(jī),請在iOS\"設(shè)置中\(zhòng)"-\"隱私\"-\"相冊\"中打開" 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- 拍的照片保存到系統(tǒng)相冊
- (void)saveImageToSystemPhotosAlbum{
UIImageWriteToSavedPhotosAlbum(self.tempImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
/// 系統(tǒng)指定的回調(diào)方法
- (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;
}