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. ...
随机推荐
- 手把手教你用Node.js爬虫爬取网站数据
个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! 开始之前请先确保自己安装了Node.js环境,还没有安装的的童鞋请自行百度 ...
- Clickhouse 时区转换
Clickhouse 时区转换 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS). OLAP场景的关键特征 大多数是读请求 数据总是以相当大的批(> 1000 ...
- 图论--2-SAT--Tarjan连通分量+拓扑排序O(N+M)模板
#include <cstdio> #include <cstring> #include <queue> #include <vector> #inc ...
- ACM卡常处理办法(虽然我到现在没遇到)
今天做预流推送,一样的代码.别人500MS(OI选手)而我5S,百思不得其解,然后我知道了还有卡常这一说. 我们今天就来看一看吧: 1.循环展开: 在缓存和寄存器允许的情况下一条语句内大量的展开运算会 ...
- POJ 1330 Nearest Common Ancestors(裸LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39596 Accept ...
- 洛谷 P1352 没有上司的舞会(树形 DP)
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
- 谷歌浏览器的F12用处及问题筛查笔记
在前端测试功能的时候,经常有些莫名其妙的错误,这个时候开发会说打开F12看一下吧,所以感觉这个开发者功能很有用,研究一下,做如下记录: Elements:左栏以DOM树形式查看网页源代码(HTML), ...
- socket编程之并发回射服务器3
在socket编程之并发回射服务器一文中,服务器采用多进程的方式实现并发,本文采用多线程的方式实现并发. 多线程相关API: // Compile and link with -pthread int ...
- ES[7.6.x]学习笔记(六)分析器
在前面的章节中,我们给大家介绍了索引中的映射类型,也就是每一个字段都有一个类型,比如:long,text,date等.这和我们的数据库非常的相似,那么它的不同之处是什么呢?对了,就是全文索引,在ES当 ...
- P1714切蛋糕(不定区间最值)
题面 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值. 小Z作为寿星,自然希望吃到的第一块蛋糕的幸运值总和最大,但小Z最多又 ...