一、功能简介

1、封装了一个按钮,点击按钮,会提示从何处获取图片:如果设备支持相机,可以从相机获取,同时还可以从手机相册获取图片。

2、选择图片后,有一个block回调,根据需求,将获得的图片拿来使用。

3、提供了初始化方法,可以灵活定义按钮,包括把返回的图片设置给按钮自己。

二、核心原理

1、UIAlertController 提示框

2、UIImagePickerController 图片拾取控制器

3、isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera 类方法,判断是否支持相机

4、遵守UIImagePickerControllerDelegate,UINavigationControllerDelegate

5、实现代理方法获得图片:- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

6、UIImageJPEGRepresentation 方法将图片压缩转换层NSData,然后写入沙盒

三、源码

1、.h文件

@interface ZQImageToolsButton : UIButton

/**
* 可以获得储存图片信息的字典,里面包含了沙盒里的图片完整路径(程序每次运行沙盒的路径可能会不同,但是图片名不变)
*
* @return
*/
-(NSDictionary * )getImageInfro; /**
* 初始化方法,点击按钮可以选择从相册或是相机(如果有相机)选择图片并返回图片
*
* @param title 按钮的名字
* @param frame 按钮的frame
* @param controller 按钮所在的控制器,弹出对话框的控制器
* @param block 获得图片后的回调
* @param imageName 储存在沙盒里图片的名字
*
* @return 返回一个按钮
*/
-(instancetype)initWithTitle:(NSString *)title frame:(CGRect)frame controller:(UIViewController *)controller imageBlock:(void(^)(UIImage *))block imageName :(NSString *)imageName; @end

2、.m文件

@interface ZQImageToolsButton() <UIImagePickerControllerDelegate,UINavigationControllerDelegate>

@property(nonatomic,weak) UIViewController * controller;

@property(nonatomic,copy) void(^imageBlock)(UIImage *) ;

@property(nonatomic,strong) NSString * imageName;

@property(nonatomic,strong) NSDictionary * imageInfro;

@end

@implementation ZQImageToolsButton

-(NSDictionary * )getImageInfro
{
return self.imageInfro; } -(instancetype)initWithTitle:(NSString *)title frame:(CGRect)frame controller:(UIViewController *)controller imageBlock:(void(^)(UIImage *))block imageName :(NSString *)imageName
{ self = [[ZQImageToolsButton alloc]initWithFrame:frame]; self.imageBlock = block; self.controller = controller; self.imageName = imageName; [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self setTitle:title forState:UIControlStateNormal]; [self addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; return self ; } - (void)btnClick:(UIButton *) btn
{ // 创建图片管理器、 跳转到相机或相册页面
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.delegate = self; imagePickerController.allowsEditing = YES; //创建弹框 UIAlertController * av = [UIAlertController alertControllerWithTitle:@"选择" message:@"从您的相册/相机选择" preferredStyle:UIAlertControllerStyleActionSheet]; //设置image管理器的源类型 __block NSInteger sourceType = ; UIAlertAction * photo = [UIAlertAction actionWithTitle:@"我的相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //图片源为相册 sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; imagePickerController.sourceType = sourceType; [self.controller presentViewController:imagePickerController animated:YES completion:^{}]; }]; UIAlertAction * camera = [UIAlertAction actionWithTitle:@"我的相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //图片源为相机 sourceType = UIImagePickerControllerSourceTypeCamera; imagePickerController.sourceType = sourceType; [self.controller presentViewController:imagePickerController animated:YES completion:^{}]; }]; UIAlertAction * cancle = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//取消
}]; //判断是否支持相机 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
[av addAction:photo];
[av addAction:camera];
[av addAction:cancle]; }
else
{
//如果不支持相机,就不用把相机按钮加入提示框了
[av addAction:photo];
[av addAction:cancle];
} [self.controller presentViewController:av animated:YES completion:nil]; } // 图片选择结束之后,走这个方法,字典存放所有图片信息
#pragma mark - image picker delegte 系统代理,返回从相册中选中的图片
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{ NSLog(@"选好图片了"); }]; //获得选中的图片了!
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; //block回调,获得图片后,交给控制器
self.imageBlock(image); // 保存图片至本地,用传进来的名字重新拼接图片名字 NSString * imgName = [NSString stringWithFormat:@"SavedImage-%@.png",self.imageName]; //拼接保存至沙盒的路径
NSString *fullPath = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:imgName]; //记录一下图片的信息,存到字典中,需要的时候可以访问
NSDictionary *dic = @{@"image":fullPath};
self.imageInfro = dic; //保存到沙盒 [self saveImage:image withName:imgName filePath:fullPath]; } //保存至沙盒
- (void) saveImage:(UIImage *)currentImage withName:(NSString *)imageName filePath:(NSString *)filePath
{
//压缩比例0.5
NSData * imageData = UIImageJPEGRepresentation(currentImage, 0.5); // 将图片写入文件
[imageData writeToFile:filePath atomically:NO];
} @end

四、其他补充

1、imagePickerController  didFinishPickingImage  这个代理方法被遗弃了。。

imagePickerController  didFinishPickingMediaWithInfo  这个方法被推荐

2、获取图片时的内存暴涨问题

(1)获取的图片全部原封不动的加载到内存中,可能会造成内存的暴涨。

(2)设置属性allowsEditing 为YES,可解决内存暴涨,对于图片进行了处理

(3)如果使用上面的第二个方法返回图片,allowsEditing也解决不了内存暴涨(什么鬼。。)

3、使用imagePickerController时,最好先判断源可用:isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera

五、扩展

1、本例没有实现图片的多选

2、本例没有实现上传图片的业务逻辑

3、小东西,供娱乐交流使用

iOS获取相册/相机图片-------自定义获取图片小控件的更多相关文章

  1. [iOS]技巧集锦:UITableView自定义Cell中的控件无法完全对齐Cell的左边界和右边界

    这是个很诡异的问题,由于一些特殊需求,我的TableView的Cell的背景色是透明,其中的控件会有背景色,第一个控件和最后一个控件我都用IB自动设了约束,对齐Cell的左边界和右边界,但是自动约束很 ...

  2. iOS - 选取相册中iCloud云上图片和视频的处理

    关于iOS选取相册中iCloud云上图片和视频  推荐看:TZImagePickerController的源码,这个是一个非常靠谱的相册选择图片视频的库 .当然也可以自己写 如下遇到的问题 工作原因, ...

  3. 获取 AlertDialog自定义的布局 的控件

    AlertDialog自定义的布局 效果图: 创建dialog方法的代码如下: 1 LayoutInflater inflater = getLayoutInflater(); 2 View layo ...

  4. [.ashx檔?泛型处理程序?]基础入门#5....ADO.NET 与 将DB里面的二进制图片还原 (范例下载 & 大型控件的ImageField)

    [.ashx檔?泛型处理程序?]基础入门#5....ADO.NET 与 将DB里面的二进制图片还原 (范例下载 & 大型控件的ImageField) http://www.dotblogs.c ...

  5. 安卓ImageView.src设置图片拉伸、填满控件的方法

    代码改变世界 安卓ImageView.src设置图片拉伸.填满控件的方法 需要给你的ImageView布局加上Android:adjustViewBounds="true"

  6. WPF 获取鼠标屏幕位置、窗口位置、控件位置

    原文:WPF 获取鼠标屏幕位置.窗口位置.控件位置 public struct POINT { public int X; public int Y; public POINT(int x, int ...

  7. android - 自定义(组合)控件 + 自定义控件外观

    转载:http://www.cnblogs.com/bill-joy/archive/2012/04/26/2471831.html android - 自定义(组合)控件 + 自定义控件外观   A ...

  8. 使用VideoView自定义一个播放器控件

    介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了.在写VideoView播放视频时候定义控制的代码全写在Actv ...

  9. WPF自定义LED风格数字显示控件

    原文:WPF自定义LED风格数字显示控件 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199988899/article/de ...

  10. 【C#】wpf自定义calendar日期选择控件的样式

    原文:[C#]wpf自定义calendar日期选择控件的样式 首先上图看下样式 原理 总览 ItemsControl内容的生成 实现 界面的实现 后台ViewModel的实现 首先上图,看下样式 原理 ...

随机推荐

  1. MaskRCNN路标:TensorFlow版本用于抠图

    MaskRCNN用于检测路标,作为更详细的目标检测,用以得到更精准的额路标位置,路标的几何中心点,用于构建更为精准的拓扑地图,减少构图误差. 抠图工具已经完成,把框抠出来,用0值表示背景. pytho ...

  2. (转)Arcgis for Js之Graphiclayer扩展详解

    http://blog.csdn.net/gisshixisheng/article/details/41208185 在前两节,讲到了两种不同方式的聚类,一种是基于距离的,一种是基于区域范围的,两种 ...

  3. element ui 日期控件范围时间限制记录、以及计算两个日期之间的天数

    日期的筛选经常会有最小的日期选择,例如:当前日期 :clearable="false" :picker-options="pickerOptions0" val ...

  4. css中有些属性的前面会加上“*”或“_(兼容IE浏览器)

    给不同浏览器识别: color{ background-color: #CC00FF; /*所有浏览器都会显示为紫色*/ background-color: #FF0000\9; /*IE6.IE7. ...

  5. js的一些老司机写法

    //取整 parseInt(a,10); //Before Math.floor(a); //Before a>>0; //Before ~~a; //After a|0; //After ...

  6. SQL With As 用法Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介

    Sql 四大排名函数(ROW_NUMBER.RANK.DENSE_RANK.NTILE)简介   排名函数是Sql Server2005新增的功能,下面简单介绍一下他们各自的用法和区别.我们新建一张O ...

  7. ie 浏览器下ajax请求来自缓存的解决方法

    如上图所示,在ie浏览器下发出的请求,如何缓存中已经出现过这条请求记录,则不会请求服务端数据,解决方法是在请求后增加一个随机数,使每次请求都不同*可以添加当前时间戳 url+'?t='+Date.no ...

  8. c/c++排坑(5) -- c语言中的申明

    C语言的申明总是令人头大,对于这块内容也一直让我头疼.希望通过这篇博客能够稍微梳理一下.材料和例子来源于<C专家编程> 一.C语言的申明的优先级规则 先来个例子,看看下面这行C代码到底是个 ...

  9. 匈牙利算法求最大匹配(HDU-4185 Oil Skimming)

    如下图:要求最多可以凑成多少对对象 大佬博客: https://blog.csdn.net/cillyb/article/details/55511666 https://blog.csdn.net/ ...

  10. 实验十二 团队作业8:软件测试与Alpha冲刺 第三天

    项目 内容 这个作业属于哪个课程 老师链接 这个作业的要求在哪里 作业链接地址 团队名称 always run 作业学习目标 (1)掌握软件测试基础技术.(2)学习迭代式增量软件开发过程(Scrum) ...