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
//
// gzhPhotoManager.m
// 图片选择
//
// Created by 郭志贺 on 2020/5/26.
// Copyright © 2020 郭志贺. All rights reserved.
// #import "gzhPhotoManager.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <Photos/Photos.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <MetalPerformanceShaders/MetalPerformanceShaders.h> @interface gzhPhotoManager () <UINavigationControllerDelegate,UIImagePickerControllerDelegate> @property (nonatomic, weak) id<gzhPhotoManagerDelegate> delegate;
@property (nonatomic, assign) CGSize photoSize;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, weak) UIViewController *controller;
@property (nonatomic, strong) UIImagePickerController *imagePickerController; @end @implementation gzhPhotoManager + (instancetype)instance {
static gzhPhotoManager * shareInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shareInstance = [[gzhPhotoManager alloc]init];
});
return shareInstance;
}
-(void)selectPhotoWithController:(UIViewController *)controller delegate:(id)target size:(CGSize)pSize{ _controller = controller;
_delegate = target;
_photoSize = pSize; UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alertVC addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[alertVC addAction:[UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [self cameraCheck:action];
}]];
[alertVC addAction:[UIAlertAction actionWithTitle:@"从手机相册中选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [self phAuthorizationCheck:action];
}]];
[_controller presentViewController:alertVC animated:YES completion:nil];
}
-(void)cameraCheck:(UIAlertAction *)action{
/*
AVAuthorizationStatusNotDetermined = 0,// 系统还未知是否访问,第一次开启相机时 AVAuthorizationStatusRestricted, // 受限制的 AVAuthorizationStatusDenied, //不允许 AVAuthorizationStatusAuthorized // 允许状态
*/ ALAuthorizationStatus author =[ALAssetsLibrary authorizationStatus];
if (author == AVAuthorizationStatusRestricted || author ==AVAuthorizationStatusDenied) {
[self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照相.设置"];
}else if (author == AVAuthorizationStatusAuthorized){
[self selectCamera:action];
}else if (author == AVAuthorizationStatusNotDetermined){
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if (granted) { //允许访问
[self selectCamera:action];
}else{ //不允许访问
[self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照相.设置"];
} }];
} } //判断是否有权限访问相簿
- (void)phAuthorizationCheck:(UIAlertAction *)action{
/*
PHAuthorizationStatusNotDetermined, 用户还没有做出选择
PHAuthorizationStatusDenied, 用户拒绝当前应用访问相册(用户当初点击了"不允许")
PHAuthorizationStatusAuthorized 用户允许当前应用访问相册(用户当初点击了"好")
PHAuthorizationStatusRestricted, 因为家长控制, 导致应用无法方法相册(跟用户的选择没有关系)
*/ // 判断授权状态
PHAuthorizationStatus statu = [PHPhotoLibrary authorizationStatus];
if (statu == PHAuthorizationStatusRestricted) {
NSLog(@"无法访问相簿--PHAuthorizationStatusRestricted");
[self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照片.设置"];
} else if (statu == PHAuthorizationStatusDenied) {
NSLog(@"无法访问相簿--PHAuthorizationStatusDenied");
[self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照片.设置"];
} else if (statu == PHAuthorizationStatusAuthorized) {
NSLog(@"可以访问相簿--PHAuthorizationStatusAuthorized");
[self selectPhotoLibrary:action];
} else if (statu == PHAuthorizationStatusNotDetermined) {
// 弹框请求用户授权
NSLog(@"第一次访问--PHAuthorizationStatusNotDetermined");
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { if (status == PHAuthorizationStatusAuthorized) {
[self selectPhotoLibrary:action];
}else{
[self alertViewWithTitle:@"提示" message:@"如需拍照,请检查拍照功能是否开启,可在:设置->隐私->照片.设置"];
} }]; } }
// 拍照
- (void)selectCamera:(UIAlertAction *)action {
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self alertViewWithTitle:@"警告" message:@"对不起,您的设备不存在相机"];
}); return;
} if (!_imagePickerController) {
_imagePickerController = [UIImagePickerController new];
_imagePickerController.delegate = self;
}
if (_photoSize.width!=&&_photoSize.height!=) {
_imagePickerController.allowsEditing = YES;
}else{
_imagePickerController.allowsEditing = NO;
} _imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
_imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
_imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
[_controller presentViewController:_imagePickerController animated:YES completion:nil];
} // 从相册中选择
- (void)selectPhotoLibrary:(UIAlertAction *)action {
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self alertViewWithTitle:@"警告" message:@"对不起,您的设备不存在相册"];
}); }
if (!_imagePickerController) {
_imagePickerController = [UIImagePickerController new];
_imagePickerController.delegate = self;
}
if (_photoSize.width!=&&_photoSize.height!=) {
_imagePickerController.allowsEditing = YES;
}else{
_imagePickerController.allowsEditing = NO;
}
_imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypeMovie];
_imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[_controller presentViewController:_imagePickerController animated:YES completion:nil]; }
#pragma mark -
#pragma mark - UIImagePickerViewController delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSString * mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]){
if (_photoSize.height!=&&_photoSize.width!=) {
UIImage *image = [self fixOrientation:[info objectForKey:UIImagePickerControllerEditedImage]];
self.image = [self scaleImage:image Tosize:self.photoSize];
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}
}else{
UIImage *image = [self fixOrientation:[info objectForKey:UIImagePickerControllerOriginalImage]];
self.image = [self scaleImage:image Tosize:self.photoSize];
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}
}
[picker dismissViewControllerAnimated:YES completion:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(selectedPhotoImage:)]) {
if (self.image) {
[self.delegate selectedPhotoImage:self.image];
} else {
[self alertViewWithTitle:@"你还没选择图片呢" message:nil];
}
}
}];
} } -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
}
// 裁剪图片
- (UIImage *)scaleImage:(UIImage *)img Tosize:(CGSize)size { CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGSize imgSize = CGSizeMake(, );
if (size.width != && size.height != ) {
imgSize = CGSizeMake(size.width, img.size.height*(size.width/img.size.width));
} else {
imgSize = CGSizeMake(screenWidth*, img.size.height*(screenWidth/img.size.width)*);
}
// 创建一个bitmap的context
// 并把它设置成为当前正在使用的context
UIGraphicsBeginImageContext(imgSize);
// 绘制改变大小的图片
[img drawInRect:CGRectMake(, , imgSize.width, imgSize.height)];
// 从当前context中创建一个改变大小后的图片
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// 使当前的context出堆栈
UIGraphicsEndImageContext();
//返回新的改变大小后的图片
return scaledImage;
} //修正image方向
- (UIImage *)fixOrientation:(UIImage *)aImage { if (aImage.imageOrientation == UIImageOrientationUp)
return aImage; 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, );
transform = CGAffineTransformRotate(transform, M_PI_2);
break; case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, , 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, );
transform = CGAffineTransformScale(transform, -, );
break; case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.height, );
transform = CGAffineTransformScale(transform, -, );
break;
default:
break;
} CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
CGImageGetBitsPerComponent(aImage.CGImage), ,
CGImageGetColorSpace(aImage.CGImage),
CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (aImage.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(,,aImage.size.height,aImage.size.width), aImage.CGImage);
break; default:
CGContextDrawImage(ctx, CGRectMake(,,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;
} // 提醒
- (void)alertViewWithTitle:(NSString *)title message:(NSString *)msg {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
[alertVC addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
[_controller presentViewController:alertVC animated:YES completion:nil];
} @end
在需要使用的地方遵循<gzhPhotoManagerDelegate>协议
//
// ViewController.m
// 图片选择
//
// Created by 郭志贺 on 2020/5/26.
// Copyright © 2020 郭志贺. All rights reserved.
// #import "ViewController.h"
#import "gzhPhotoManager.h" /** 屏幕高度 */
#define ScreenH [UIScreen mainScreen].bounds.size.height
/** 屏幕宽度 */
#define ScreenW [UIScreen mainScreen].bounds.size.width @interface ViewController ()<gzhPhotoManagerDelegate>
@property(nonatomic,strong)UIImageView * selectImageView;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. _selectImageView = [[UIImageView alloc]init];
_selectImageView.frame = CGRectMake(, , ScreenW, ScreenH);
_selectImageView.contentMode = UIViewContentModeScaleAspectFit;
_selectImageView.clipsToBounds = YES;
_selectImageView.backgroundColor = [UIColor purpleColor];
[self.view addSubview:_selectImageView]; _selectImageView.userInteractionEnabled = YES;
UITapGestureRecognizer * selectPhotoTapGes = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(selectPhoto:)];
[_selectImageView addGestureRecognizer:selectPhotoTapGes]; }
-(void)selectPhoto:(UITapGestureRecognizer *)taps{
//调用
[[gzhPhotoManager instance]selectPhotoWithController:self delegate:self size:CGSizeMake(ScreenW, ScreenW)]; }
-(void)selectedPhotoImage:(UIImage *)image{ _selectImageView.image = image; }
@end
可直接复制使用,新手见解,如有遗漏或不足敬请告知。

iOS开发图片选择的更多相关文章
- iOS开发-图片高斯模糊效果
iOS开发的时候有的时候需要将图片设置模糊,或者通过点击下拉方法,去除模糊,一切都是为了应用更受用户欢迎,iOS7之后半透明模糊效果得到大范围使用的比较大,现在也可以看到很多应用局部用到了图片模糊效果 ...
- iOS开发-照片选择
本来想做个注册登录的表单的,想想还是先做个简单的头像选择,一般情况下不管是内部管理系统还是面向公众的互联网公司,注册登录是免不了的,用户头像上传是免不了的,尤其是企业用户,上传了自己的图片才感觉自己买 ...
- iOS开发图片加载的内存问题及优化方案
原创作者:Magic-Unique 原文地址:https://github.com/Magic-Unique/HXImage猿吧 - 资源共享论坛: http://www.coderbar.cn 做最 ...
- iOS 开发图片资源选择png格式还是jpg格式
对于iOS本地应用程序来说最简单的答案就是始终使用PNG,除非你有非常非常好的理由不用它. 当iOS应用构建的时候,Xcode会通过一种方式优化.png文件而不会优化其它文件格式.它优化得相当的好 他 ...
- iOS 开发该选择Blocks还是Delegates
http://www.cocoachina.com/ios/20150925/13525.html 前文:网络上找了很多关于delegation和block的使用场景,发现没有很满意的解释,后来无意中 ...
- IOS开发-图片上传
目前IOS端开发,图片上传到服务器分为两种,一种是直接上到服务器,一种是借助第三方储存(减少服务器压力). 一.直接上传到服务器 /** * 代码演示 */ //*******UIImagePNGRe ...
- iOS开发——图片轮播图+单选选项
由于公司开发需要,需要滚动每道评测题, 并且一道评测题单项选择,按钮和文字都可点击选中 (单选比多选复杂一点,但是原理差不多) 1.当初任务紧,代码也没有优化,仅供思路参考,先放几张图 2.代码部分 ...
- IOS开发-图片尺寸
在这篇文章当中,不会讲述关于具体px pt,分辨率,像素的问题,在这篇文章中,只会谈及到一些展现的问题 如果想了解更多关于pt,px之间的关系可以自行到百度查找相关的答案,或者到以下地址阅读更多相关的 ...
- ios开发图片点击放大
图片点击放大,再次点击返回原视图.完美封装,一个类一句代码即可调用.IOS完美实现 创建了一个专门用于放大图片的类,以下为.h文件 #import <Foundation/Foundation. ...
随机推荐
- 2019年 ICPC亚洲区预赛(上海赛区)总结
首先,我要说,我输了,输给了自己的无知,输给了自己的心态与实力. 上海区域赛,打铁而归,最终还是没有比过自己SLG的朋友.要说什么呢?实力的差距,还是说给自己的失败找借口?不能进入金牌区,为什么铜牌区 ...
- 图论--差分约束--POJ 3159 Candies
Language:Default Candies Time Limit: 1500MS Memory Limit: 131072K Total Submissions: 43021 Accep ...
- UVA-1 #1. A + B Problem
给你两个数 aa 和 bb,请输出他们的和. 输入格式 一行,两个用空格隔开的整数 aa 和 bb. 输出格式 一个整数,表示 a+ba+b. 样例一 input 2 3 output 5 限制与约定 ...
- Scrapy爬虫框架基本使用
scrapyhub上有些视频简单介绍scrapy如何学习的(貌似要FQ):https://helpdesk.scrapinghub.com/support/solutions/articles/220 ...
- AntDesignPro的权限控制和动态路由
最近看了AntDesignPro关于权限控制的官方文档以及自己框架里权限控制的实现,总结一下. 先贴一下官网上关于权限控制的图有利于理解 步骤如下: 判断是否有 AccessToken 如果没有则跳转 ...
- Spring官网阅读(四)BeanDefinition(上)
前面几篇文章已经学习了官网中的1.2,1.3,1.4三小结,主要是容器,Bean的实例化及Bean之间的依赖关系等.这篇文章,我们继续官网的学习,主要是BeanDefinition的相关知识,这是Sp ...
- VA01信贷使用
1业务场景 业务在正式机中发现,当使用VA01输入客户编号回车后会报错 2解决方法 1. SE24进入CL_IM_UKM_SD_FSCM_INTEGR1 2. 双击方法IF_EX_BADI_SD_CM ...
- JS作用域和变量提升看这一篇就够了
作用域是JS中一个很基础但是很重要的概念,面试中也经常出现,本文会详细深入的讲解这个概念及其他相关的概念,包括声明提升,块级作用域,作用域链及作用域链延长等问题. 什么是作用域 第一个问题就是我们要弄 ...
- Mybatis极速入门
搭建mybatis的环境 导入相关jar包 mybatis-3.5.3.jar commons-logging-1.1.1.jar log4j-1.2.16.jar cglib-2.2.2.jar a ...
- SonarQube搭建手记
前提 这篇文章记录的是SonarQube服务搭建的详细过程,应用于云迁移后的PipleLine的代码扫描环节. 笔者有软件版本升级强迫症,一般喜欢使用软件的最新版本,编写此文的时候(2020-05-1 ...