2020年5月26日星期二

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

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 BFPhotoManagerDelegate;@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;@endNS_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 delegate179 - (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的context224  // 并把它设置成为当前正在使用的context225  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 context304  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.height14 /** 屏幕宽度 */15 #define ScreenW [UIScreen mainScreen].bounds.size.width16 17 @interface ViewController ()<gzhPhotoManagerDelegate>18 @property(nonatomic,strong)UIImageView * selectImageView;19 @end20 21 @implementation ViewController22 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

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


没有评论:

发表评论