iOS 系統(tǒng)- 相冊與 拍照

#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;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末路狮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绰筛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件描融,死亡現(xiàn)場離奇詭異铝噩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)窿克,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門骏庸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人年叮,你說我怎么就攤上這事具被。” “怎么了只损?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵一姿,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么喧锦? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮衬横,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘终蒂。我一直安慰自己蜂林,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布拇泣。 她就那樣靜靜地躺著噪叙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霉翔。 梳的紋絲不亂的頭發(fā)上睁蕾,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼子眶。 笑死瀑凝,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的臭杰。 我是一名探鬼主播粤咪,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼渴杆!你這毒婦竟也來了寥枝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤磁奖,失蹤者是張志新(化名)和其女友劉穎囊拜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比搭,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡艾疟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了敢辩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡弟疆,死狀恐怖戚长,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情怠苔,我是刑警寧澤同廉,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站柑司,受9級特大地震影響迫肖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜攒驰,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一蟆湖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧玻粪,春花似錦隅津、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至很洋,卻和暖如春充蓝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工谓苟, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留官脓,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓娜谊,卻偏偏與公主長得像确买,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纱皆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容