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
可直接复制使用,新手见解,如有遗漏或不足敬请告知。
No comments:
Post a Comment