• iOS开发从相册选择照片或拍照


    一行代码搞定图片选择

    //
    //  gzhPhotoManager.h
    //  图片选择
    //
    //  Created by 郭志贺 on 2020/5/26.
    //  Copyright © 2020 郭志贺. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "ViewController.h"
    
    NS_ASSUME_NONNULL_BEGIN
    @protocol gzhPhotoManagerDelegate;
    @interface gzhPhotoManager : NSObject
    
    +(instancetype)instance;
    
    /// 选择图片
    /// @param controller 当前控制器
    /// @param target 代理
    /// @param pSize 选择照片尺寸 尺寸传(0,0)不进行裁剪
    - (void)selectPhotoWithController:(UIViewController *)controller delegate:(id)target size:(CGSize)pSize;
    
    @end
    
    
    @protocol gzhPhotoManagerDelegate <NSObject>
    
    - (void)selectedPhotoImage:(UIImage *)image;
    
    @end
    NS_ASSUME_NONNULL_END
      1 //
      2 //  gzhPhotoManager.m
      3 //  图片选择
      4 //
      5 //  Created by 郭志贺 on 2020/5/26.
      6 //  Copyright © 2020 郭志贺. All rights reserved.
      7 //
      8 
      9 #import "gzhPhotoManager.h"
     10 #import <MobileCoreServices/MobileCoreServices.h>
     11 #import <Photos/Photos.h>
     12 #import <AssetsLibrary/AssetsLibrary.h>
     13 #import <MetalPerformanceShaders/MetalPerformanceShaders.h>
     14 
     15 @interface gzhPhotoManager () <UINavigationControllerDelegate,UIImagePickerControllerDelegate>
     16 
     17 @property (nonatomic, weak) id<gzhPhotoManagerDelegate> delegate;
     18 @property (nonatomic, assign) CGSize photoSize;
     19 @property (nonatomic, strong) UIImage *image;
     20 @property (nonatomic, weak) UIViewController *controller;
     21 @property (nonatomic, strong) UIImagePickerController *imagePickerController;
     22 
     23 @end
     24 
     25 
     26 @implementation gzhPhotoManager
     27 
     28 + (instancetype)instance {
     29     static gzhPhotoManager * shareInstance = nil;
     30     static dispatch_once_t onceToken;
     31     dispatch_once(&onceToken, ^{
     32         shareInstance = [[gzhPhotoManager alloc]init];
     33     });
     34     return shareInstance;
     35 }
     36 -(void)selectPhotoWithController:(UIViewController *)controller delegate:(id)target size:(CGSize)pSize{
     37     
     38     _controller = controller;
     39     _delegate = target;
     40     _photoSize = pSize;
     41     
     42     UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
     43     [alertVC addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
     44     [alertVC addAction:[UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
     45         
     46         [self cameraCheck:action];
     47     }]];
     48     [alertVC addAction:[UIAlertAction actionWithTitle:@"从手机相册中选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
     49        
     50         [self phAuthorizationCheck:action];
     51     }]];
     52     [_controller presentViewController:alertVC animated:YES completion:nil];
     53 }
     54 -(void)cameraCheck:(UIAlertAction *)action{
     55     /*
     56      AVAuthorizationStatusNotDetermined = 0,// 系统还未知是否访问,第一次开启相机时
     57      
     58      AVAuthorizationStatusRestricted, // 受限制的
     59      
     60      AVAuthorizationStatusDenied, //不允许
     61      
     62      AVAuthorizationStatusAuthorized // 允许状态
     63      */
     64     
     65     ALAuthorizationStatus author =[ALAssetsLibrary authorizationStatus];
     66     if (author == AVAuthorizationStatusRestricted || author ==AVAuthorizationStatusDenied) {
     67         [self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照相.设置"];
     68     }else if (author == AVAuthorizationStatusAuthorized){
     69         [self selectCamera:action];
     70     }else if (author == AVAuthorizationStatusNotDetermined){
     71         [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
     72             
     73             if (granted) {
     74                 
     75                 //允许访问
     76                 [self selectCamera:action];
     77             }else{
     78                 
     79                 //不允许访问
     80                 [self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照相.设置"];
     81             }
     82             
     83         }];
     84     }
     85     
     86     
     87 }
     88 
     89 //判断是否有权限访问相簿
     90 - (void)phAuthorizationCheck:(UIAlertAction *)action{
     91     /*
     92      PHAuthorizationStatusNotDetermined,     用户还没有做出选择
     93      PHAuthorizationStatusDenied,            用户拒绝当前应用访问相册(用户当初点击了"不允许")
     94      PHAuthorizationStatusAuthorized         用户允许当前应用访问相册(用户当初点击了"好")
     95      PHAuthorizationStatusRestricted,        因为家长控制, 导致应用无法方法相册(跟用户的选择没有关系)
     96      */
     97     
     98     // 判断授权状态
     99     PHAuthorizationStatus statu = [PHPhotoLibrary authorizationStatus];
    100     if (statu == PHAuthorizationStatusRestricted) {
    101         NSLog(@"无法访问相簿--PHAuthorizationStatusRestricted");
    102         [self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照片.设置"];
    103     } else if (statu == PHAuthorizationStatusDenied) {
    104         NSLog(@"无法访问相簿--PHAuthorizationStatusDenied");
    105         [self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照片.设置"];
    106     } else if (statu == PHAuthorizationStatusAuthorized) {
    107         NSLog(@"可以访问相簿--PHAuthorizationStatusAuthorized");
    108         [self selectPhotoLibrary:action];
    109     } else if (statu == PHAuthorizationStatusNotDetermined) {
    110         // 弹框请求用户授权
    111         NSLog(@"第一次访问--PHAuthorizationStatusNotDetermined");
    112         [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    113             
    114             if (status == PHAuthorizationStatusAuthorized) {
    115                 [self selectPhotoLibrary:action];
    116             }else{
    117                 [self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照片.设置"];
    118             }
    119             
    120         }];
    121         
    122     }
    123     
    124     
    125 }
    126 // 拍照
    127 - (void)selectCamera:(UIAlertAction *)action {
    128     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    129         dispatch_async(dispatch_get_main_queue(), ^{
    130             [self alertViewWithTitle:@"警告" message:@"对不起,您的设备不存在相机"];
    131         });
    132         
    133         return;
    134     }
    135 
    136 
    137     if (!_imagePickerController) {
    138         _imagePickerController = [UIImagePickerController new];
    139         _imagePickerController.delegate = self;
    140     }
    141     if (_photoSize.width!=0&&_photoSize.height!=0) {
    142         _imagePickerController.allowsEditing = YES;
    143     }else{
    144         _imagePickerController.allowsEditing = NO;
    145     }
    146 
    147     _imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
    148     _imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    149     _imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
    150     [_controller presentViewController:_imagePickerController animated:YES completion:nil];
    151 }
    152 
    153 // 从相册中选择
    154 - (void)selectPhotoLibrary:(UIAlertAction *)action {
    155     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
    156         dispatch_async(dispatch_get_main_queue(), ^{
    157              [self alertViewWithTitle:@"警告" message:@"对不起,您的设备不存在相册"];
    158         });
    159       
    160     }
    161     if (!_imagePickerController) {
    162         _imagePickerController = [UIImagePickerController new];
    163         _imagePickerController.delegate = self;
    164     }
    165     if (_photoSize.width!=0&&_photoSize.height!=0) {
    166         _imagePickerController.allowsEditing = YES;
    167     }else{
    168         _imagePickerController.allowsEditing = NO;
    169     }
    170     _imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypeMovie];
    171     _imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    172     [_controller presentViewController:_imagePickerController animated:YES completion:nil];
    173     
    174     
    175     
    176 }
    177 #pragma mark -
    178 #pragma mark - UIImagePickerViewController delegate
    179 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    180     
    181     NSString * mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    182     if ([mediaType isEqualToString:(NSString *)kUTTypeImage]){
    183         if (_photoSize.height!=0&&_photoSize.width!=0) {
    184             UIImage *image = [self fixOrientation:[info objectForKey:UIImagePickerControllerEditedImage]];
    185             self.image = [self scaleImage:image Tosize:self.photoSize];
    186             if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
    187                 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    188             }
    189         }else{
    190             UIImage *image = [self fixOrientation:[info objectForKey:UIImagePickerControllerOriginalImage]];
    191             self.image = [self scaleImage:image Tosize:self.photoSize];
    192             if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
    193                 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    194             }
    195         }
    196         [picker dismissViewControllerAnimated:YES completion:^{
    197             if (self.delegate && [self.delegate respondsToSelector:@selector(selectedPhotoImage:)]) {
    198                 if (self.image) {
    199                     [self.delegate selectedPhotoImage:self.image];
    200                 } else {
    201                     [self alertViewWithTitle:@"你还没选择图片呢" message:nil];
    202                 }
    203             }
    204         }];
    205     }
    206     
    207     
    208 }
    209 
    210 -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    211     [picker dismissViewControllerAnimated:YES completion:nil];
    212 }
    213 // 裁剪图片
    214 - (UIImage *)scaleImage:(UIImage *)img Tosize:(CGSize)size {
    215     
    216     CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    217     CGSize imgSize = CGSizeMake(0, 0);
    218     if (size.width != 0 && size.height != 0) {
    219         imgSize = CGSizeMake(size.width, img.size.height*(size.width/img.size.width));
    220     } else {
    221         imgSize = CGSizeMake(screenWidth*2, img.size.height*(screenWidth/img.size.width)*2);
    222     }
    223     // 创建一个bitmap的context
    224     // 并把它设置成为当前正在使用的context
    225     UIGraphicsBeginImageContext(imgSize);
    226     // 绘制改变大小的图片
    227     [img drawInRect:CGRectMake(0, 0, imgSize.width, imgSize.height)];
    228     // 从当前context中创建一个改变大小后的图片
    229     UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    230     // 使当前的context出堆栈
    231     UIGraphicsEndImageContext();
    232     //返回新的改变大小后的图片
    233     return scaledImage;
    234 }
    235 
    236 
    237 //修正image方向
    238 - (UIImage *)fixOrientation:(UIImage *)aImage {
    239     
    240 
    241     if (aImage.imageOrientation == UIImageOrientationUp)
    242         return aImage;
    243     
    244     CGAffineTransform transform = CGAffineTransformIdentity;
    245     
    246     switch (aImage.imageOrientation) {
    247         case UIImageOrientationDown:
    248         case UIImageOrientationDownMirrored:
    249             transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
    250             transform = CGAffineTransformRotate(transform, M_PI);
    251             break;
    252             
    253         case UIImageOrientationLeft:
    254         case UIImageOrientationLeftMirrored:
    255             transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
    256             transform = CGAffineTransformRotate(transform, M_PI_2);
    257             break;
    258             
    259         case UIImageOrientationRight:
    260         case UIImageOrientationRightMirrored:
    261             transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
    262             transform = CGAffineTransformRotate(transform, -M_PI_2);
    263             break;
    264         default:
    265             break;
    266     }
    267     
    268     switch (aImage.imageOrientation) {
    269         case UIImageOrientationUpMirrored:
    270         case UIImageOrientationDownMirrored:
    271             transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
    272             transform = CGAffineTransformScale(transform, -1, 1);
    273             break;
    274             
    275         case UIImageOrientationLeftMirrored:
    276         case UIImageOrientationRightMirrored:
    277             transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
    278             transform = CGAffineTransformScale(transform, -1, 1);
    279             break;
    280         default:
    281             break;
    282     }
    283 
    284     CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
    285                                              CGImageGetBitsPerComponent(aImage.CGImage), 0,
    286                                              CGImageGetColorSpace(aImage.CGImage),
    287                                              CGImageGetBitmapInfo(aImage.CGImage));
    288     CGContextConcatCTM(ctx, transform);
    289     switch (aImage.imageOrientation) {
    290         case UIImageOrientationLeft:
    291         case UIImageOrientationLeftMirrored:
    292         case UIImageOrientationRight:
    293         case UIImageOrientationRightMirrored:
    294             // Grr...
    295             CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
    296             break;
    297             
    298         default:
    299             CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
    300             break;
    301     }
    302     
    303     // And now we just create a new UIImage from the drawing context
    304     CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    305     UIImage *img = [UIImage imageWithCGImage:cgimg];
    306     CGContextRelease(ctx);
    307     CGImageRelease(cgimg);
    308     return img;
    309 }
    310 
    311 
    312 // 提醒
    313 - (void)alertViewWithTitle:(NSString *)title message:(NSString *)msg {
    314     UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
    315     [alertVC addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
    316     [_controller presentViewController:alertVC animated:YES completion:nil];
    317 }
    318 
    319 
    320 @end

    在需要使用的地方遵循<gzhPhotoManagerDelegate>协议

     1 //
     2 //  ViewController.m
     3 //  图片选择
     4 //
     5 //  Created by 郭志贺 on 2020/5/26.
     6 //  Copyright © 2020 郭志贺. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 #import "gzhPhotoManager.h"
    11 
    12 /** 屏幕高度 */
    13 #define ScreenH [UIScreen mainScreen].bounds.size.height
    14 /** 屏幕宽度 */
    15 #define ScreenW [UIScreen mainScreen].bounds.size.width
    16 
    17 @interface ViewController ()<gzhPhotoManagerDelegate>
    18 @property(nonatomic,strong)UIImageView * selectImageView;
    19 @end
    20 
    21 @implementation ViewController
    22 
    23 - (void)viewDidLoad {
    24     [super viewDidLoad];
    25     // Do any additional setup after loading the view.
    26     
    27     _selectImageView = [[UIImageView alloc]init];
    28     _selectImageView.frame = CGRectMake(0, 0, ScreenW, ScreenH);
    29     _selectImageView.contentMode = UIViewContentModeScaleAspectFit;
    30     _selectImageView.clipsToBounds = YES;
    31     _selectImageView.backgroundColor = [UIColor purpleColor];
    32     [self.view addSubview:_selectImageView];
    33     
    34     _selectImageView.userInteractionEnabled = YES;
    35     UITapGestureRecognizer * selectPhotoTapGes = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(selectPhoto:)];
    36     [_selectImageView addGestureRecognizer:selectPhotoTapGes];
    37     
    38 }
    39 -(void)selectPhoto:(UITapGestureRecognizer *)taps{
    40     //调用
    41     [[gzhPhotoManager instance]selectPhotoWithController:self delegate:self size:CGSizeMake(ScreenW, ScreenW)];
    42     
    43 }
    44 -(void)selectedPhotoImage:(UIImage *)image{
    45     
    46     _selectImageView.image = image;
    47     
    48     
    49 }
    50 @end

    可直接复制使用,新手见解,如有遗漏或不足敬请告知。

  • 相关阅读:
    LeetCode题解 | [简单-数组] 485.最大连续1的个数
    PAT乙级真题 | 1032 挖掘机技术哪家强
    [leetcode]两个列表的最小索引总和
    【leetCode】两个数组的交集
    手写hashMap(非红黑树)
    Redis 删除数据后不能自动释放内存的问题
    Spring @Async/@Transactional 失效的原因及解决方案
    完全平方数问题
    用队列实现栈
    memcached安装踩坑
  • 原文地址:https://www.cnblogs.com/guozhihe/p/12965927.html
Copyright © 2020-2023  润新知