如今的App都很流行圆形的头像,比方QQ右上角的头像,今日头条的头像等等。这已经成为App设计的趋势了。今天我们就来简单实现一下这个功能,我还会把从手机拍照中或者图库中取出作为头像的照片存储到应用程序沙盒中。

下次进入应用的时候还会显示该头像。

演示样例代码上传至:https://github.com/chenyufeng1991/AvatarPhoto
 。

(1)该demo使用storyboard进行实现。首先拖入一个ImageView用来显示头像和一个button。

并拖拽到代码中进行绑定。图片绑定IBOutlet,button绑定IBAction。storyboard的设计效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">。

(2)如今要设置矩形的ImageView为圆形,同一时候能够设置该控件的边框颜色和宽度。

实现代码例如以下:

  1. - (void)setCirclePhoto{
  2. //avatarImage是图片控件;
  3. [self.avatarImage.layer setCornerRadius:CGRectGetHeight([self.avatarImage bounds]) / 2];
  4. self.avatarImage.layer.masksToBounds = true;
  5.  
  6. //能够依据需求设置边框宽度、颜色
  7. self.avatarImage.layer.borderWidth = 1;
  8. self.avatarImage.layer.borderColor = [[UIColor blackColor] CGColor];
  9. //设置图片;
  10. self.avatarImage.layer.contents = (id)[[UIImage imageNamed:@"avatar.png"] CGImage];
  11.  
  12. }

(3)如今执行程序。能够发现ImageView已经设置为圆形了。

以下将会从手机中读取照片,这里的方法是假设你的设备(真机)支持拍照,那么默认会打开照相机,进行拍照;假设你的设备不支持拍照(模拟器),那么就会默认打开图库。实现方式例如以下:selectPhoto是button的点击事件。

  1. - (IBAction)selectPhoto:(id)sender {
  2.  
  3. if ([self.imagePickerPopover isPopoverVisible]) {
  4. [self.imagePickerPopover dismissPopoverAnimated:YES];
  5. self.imagePickerPopover = nil;
  6. return;
  7. }
  8.  
  9. UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
  10. imagePicker.editing = YES;
  11.  
  12. //假设设备支持相机。就使用拍照技术
  13. //否则让用户从照片库中选择照片
  14. if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
  15. {
  16. imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
  17. }
  18. else{
  19. imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  20. }
  21.  
  22. imagePicker.delegate = self;
  23.  
  24. //同意编辑图片
  25. imagePicker.allowsEditing = YES;
  26.  
  27. //创建UIPopoverController对象前先检查当前设备是不是ipad
  28. if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
  29. self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
  30. self.imagePickerPopover.delegate = self;
  31. [self.imagePickerPopover presentPopoverFromBarButtonItem:sender
  32. permittedArrowDirections:UIPopoverArrowDirectionAny
  33. animated:YES];
  34. }
  35. else
  36. {
  37. [self presentViewController:imagePicker animated:YES completion:nil];
  38. }
  39. }
  40.  
  41. -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
  42. {
  43. //通过info字典获取选择的照片
  44. UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];
  45.  
  46. //以itemKey为键,将照片存入ImageStore对象中
  47. [[MyImageStore sharedStore] setImage:image forKey:@"CYFStore"];
  48.  
  49. //将照片放入UIImageView对象
  50. self.avatarImage.image = image;
  51.  
  52. //推断UIPopoverController对象是否存在
  53. if (self.imagePickerPopover) {
  54. [self.imagePickerPopover dismissPopoverAnimated:YES];
  55. self.imagePickerPopover = nil;
  56. }
  57. else
  58. {
  59. //关闭以模态形式显示的UIImagePickerController
  60. [self dismissViewControllerAnimated:YES completion:nil];
  61. }
  62. }

(4)执行以上程序,就已经能够从照相机或者图库中取出照片放到圆形ImageView中了。我解释一下上面的一行代码。

  1. [[MyImageStore sharedStore] setImage:image forKey:@"CYFStore"];

这行代码是把该照片存储到应用沙盒中,也使用键值对的方式来存储。

下次程序启动后,直接会读取该图片。

等下我会来实现这个MyImageStore类。

同一时候。也要声明一个属性:

  1. @property (strong, nonatomic) UIPopoverController *imagePickerPopover;

UIPopoverController对象用来打开照相机。

(5)以下将要来实现把图片存储到沙盒(文件存储)中(代码较多。可直接參考源码)

  1. +(instancetype)sharedStore
  2. {
  3. static MyImageStore *instance = nil;
  4.  
  5. //确保多线程中仅仅创建一次对象,线程安全的单例
  6. static dispatch_once_t onceToken;
  7. dispatch_once(&onceToken, ^{
  8. instance = [[self alloc] initPrivate];
  9. });
  10.  
  11. return instance;
  12. }
  13.  
  14. -(instancetype)initPrivate
  15. {
  16. self = [super init];
  17. if (self) {
  18. _dictionary = [[NSMutableDictionary alloc] init];
  19.  
  20. //注冊为低内存通知的观察者
  21. NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  22. [nc addObserver:self
  23. selector:@selector(clearCaches:)
  24. name:UIApplicationDidReceiveMemoryWarningNotification
  25. object:nil];
  26. }
  27. return self;
  28. }
  29.  
  30. -(void)setImage:(UIImage *)image forKey:(NSString *)key
  31. {
  32. [self.dictionary setObject:image forKey:key];
  33.  
  34. //获取保存图片的全路径
  35. NSString *path = [self imagePathForKey:key];
  36.  
  37. //从图片提取JPEG格式的数据,第二个參数为图片压缩參数
  38. NSData *data = UIImageJPEGRepresentation(image, 0.5);
  39. //以PNG格式提取图片数据
  40. //NSData *data = UIImagePNGRepresentation(image);
  41.  
  42. //将图片数据写入文件
  43. [data writeToFile:path atomically:YES];
  44. }
  45.  
  46. -(UIImage *)imageForKey:(NSString *)key
  47. {
  48. //return [self.dictionary objectForKey:key];
  49. UIImage *image = [self.dictionary objectForKey:key];
  50. if (!image) {
  51. NSString *path = [self imagePathForKey:key];
  52.  
  53. image = [UIImage imageWithContentsOfFile:path];
  54. if (image) {
  55. [self.dictionary setObject:image forKey:key];
  56. }
  57. else
  58. {
  59. NSLog(@"Error: unable to find %@", [self imagePathForKey:key]);
  60. }
  61. }
  62. return image;
  63. }
  64.  
  65. -(NSString *)imagePathForKey:(NSString *)key
  66. {
  67. NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  68. NSString *documentDirectory = [documentDirectories firstObject];
  69. return [documentDirectory stringByAppendingPathComponent:key];
  70. }
  71.  
  72. -(void)clearCaches:(NSNotification *)n
  73. {
  74. NSLog(@"Flushing %ld images out of the cache", (unsigned long)[self.dictionary count]);
  75. [self.dictionary removeAllObjects];
  76. }

(6)执行程序,实现效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">。

总结,当选择完图片之后,就会存储到文件里,当下次程序又一次启动,就会从文件里自己主动读出该图片进行显示。在实际开发中。图片可能是从网络获取的。而且选择完图片后也会传到server,当然你也能够在本地做一个缓存。提高效率。

该模块能够进行扩展,也能够直接拿到项目中使用。

博客更新:

假设我不想让图片在取完之后进行截取编辑,能够设置:

  1. imagePicker.allowsEditing = false;

同一时候把:

  1. //通过info字典获取选择的照片
  2. UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];

改动为:

  1. //通过info字典获取选择的照片
  2. UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];

上面都没有涉及把一张图片存储到手机的图库中,下面方法能够把拍照后的Image保存到用户手机中:当中第三个參数能够写一个回调方法,也就是把照片存储到图库后的方法回调。

  1. //把一张照片保存到图库中,此时不管是这张照片是照相机拍的还是本身从图库中取出的,都会保存到图库中;
  2. UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);

假设我们要把一张图片进行保存或者使用网络传输。使用NSData较为合适,并进行压缩:

  1. //压缩图片,假设图片要上传到server或者网络,则须要运行该步骤(压缩),第二个參数是压缩比例,转化为NSData类型。
  2. NSData *fileData = UIImageJPEGRepresentation(image, 1.0);

应用优化与更新:

事实上在让用户选择图片的时候,应该也要用户选择是打开照相机还是图库。

以下的代码优化是弹出选择框(UIAlertController),主要就是设置sourceType属性。现把点击button的事件处理改动例如以下:代码更新已经提交至:https://github.com/chenyufeng1991/AvatarPhoto

  1. - (IBAction)selectPhoto:(id)sender {
  2.  
  3. if ([self.imagePickerPopover isPopoverVisible]) {
  4. [self.imagePickerPopover dismissPopoverAnimated:YES];
  5. self.imagePickerPopover = nil;
  6. return;
  7. }
  8.  
  9. UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
  10. imagePicker.editing = YES;
  11. imagePicker.delegate = self;
  12.  
  13. /*
  14. 假设这里allowsEditing设置为false。则以下的UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];
  15. 应该改为: UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
  16. 也就是改为原图像。而不是编辑后的图像。
  17.  
  18. */
  19.  
  20. //同意编辑图片
  21. imagePicker.allowsEditing = YES;
  22. /*
  23. 这里以弹出选择框的形式让用户选择是打开照相机还是图库
  24. */
  25.  
  26. //初始化提示框。
  27. UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请选择打开方式" message:nil preferredStyle: UIAlertControllerStyleActionSheet];
  28.  
  29. [alert addAction:[UIAlertAction actionWithTitle:@"照相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  30.  
  31. imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;//设置为照相机打开;
  32.  
  33. //创建UIPopoverController对象前先检查当前设备是不是ipad
  34. if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
  35. self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
  36. self.imagePickerPopover.delegate = self;
  37. [self.imagePickerPopover presentPopoverFromBarButtonItem:sender
  38. permittedArrowDirections:UIPopoverArrowDirectionAny
  39. animated:YES];
  40. }
  41. else{
  42. [self presentViewController:imagePicker animated:YES completion:nil];
  43.  
  44. }
  45. }]];
  46.  
  47. [alert addAction:[UIAlertAction actionWithTitle:@"相冊" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  48.  
  49. imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//设置为图库打开。
  50.  
  51. //创建UIPopoverController对象前先检查当前设备是不是ipad
  52. if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
  53. self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
  54. self.imagePickerPopover.delegate = self;
  55. [self.imagePickerPopover presentPopoverFromBarButtonItem:sender
  56. permittedArrowDirections:UIPopoverArrowDirectionAny
  57. animated:YES];
  58. }
  59. else{
  60. [self presentViewController:imagePicker animated:YES completion:nil];
  61. }
  62. }]];
  63.  
  64. [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
  65. //取消;
  66. }]];
  67.  
  68. //弹出提示框;
  69. [self presentViewController:alert animated:true completion:nil];
  70. }

实现效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

github主页:https://github.com/chenyufeng1991 

欢迎大家訪问!

iOS开发——定制圆形头像与照相机图库的使用的更多相关文章

  1. iOS开发-定制多样式二维码

    iOS开发-定制多样式二维码   二维码/条形码是按照某种特定的几何图形按一定规律在平台(一维/二维方向上)分布的黑白相间的图形纪录符号信息.使用若干个与二进制对应的几何形体来表示文字数值信息. 最常 ...

  2. Android自定义控件实例,圆形头像(图库 + 裁剪+设置),上传头像显示为圆形,附源码

    Android项目开发中经常会遇见需要实现圆角或者圆形的图片功能,如果仅仅使用系统自带的ImageView控件显然无法实现此功能,所以通过系列文章的形式由简到繁全方位的介绍一下此功能的实现,巩固一下自 ...

  3. iOS实现头像选取(照相或者图片库)、大小等比缩放、生成圆形头像

    //弹出actionsheet.选择获取头像的方式 //从相册获取图片 -(void)takePictureClick:(UIButton *)sender { // /*注:使用,需要实现以下协议: ...

  4. Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...

  5. 【iOS开发-80】Quartz2D绘图简介:直线/圆形/椭圆/方形以及上下文栈管理CGContextSaveGState/CGContextRestoreGState

    本文转载至 http://blog.csdn.net/weisubao/article/details/41282457 - (void)drawRect:(CGRect)rect { //获得当前上 ...

  6. 【iOS开发-80】Quartz2D画图简单介绍:直线/圆形/椭圆/方形以及上下文栈管理CGContextSaveGState/CGContextRestoreGState

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2Vpc3ViYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  7. iOS 画圆形头像

    demo下载地址:http://pan.baidu.com/s/1mgBf6YG _logoImageView.image = [self getEllipseImageWithImage:[UIIm ...

  8. iOS:iOS开发非常全的三方库、插件等等

    iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...

  9. iOS开发之资料收集

    github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自github:https://github ...

随机推荐

  1. scws

    SCWS 是 Simple Chinese Word Segmentation 的首字母缩写(即:简易中文分词系统). 这是一套基于词频词典的机械式中文分词引擎,它能将一整段的中文文本基本正确地切分成 ...

  2. HDU3533 Escape

    题目: The students of the HEU are maneuvering for their military training. The red army and the blue a ...

  3. DotNetCasClient加载失败问题分析

    最近公司在接入整理单点登录方案的时候,选择了CAS方案,实际版本采用了4.0.当我们把服务端附属完毕,基于.NET平台Web版的客户端DotNetCasClient进行定制化修改后,在测试环境通过.然 ...

  4. Asp.net三种事务处理

    事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...

  5. Spring Cloud (2) 服务消费者-基础

    LoadBalancerClient 使用Spring Cloud提供的负载均衡器客户端来实现服务的消费. 首先创建一个服务消费者工程,命名为com.david.consumer,并在pom.xml中 ...

  6. android黑科技系列——爆破一款应用的签名验证问题

    一.前言 在之前的文章中说过Android中的安全和破解是相辅相成的,为了防止被破解,很多应用做了一些防护策略,但是防护策略也是分等级,一般简单的策略就是混淆代码和签名校验,而对于签名校验很多应用都是 ...

  7. TCP/IP,必知必会的

    文章目录 前言 TCP/IP模型 数据链路层 网络层 ping Traceroute TCP/UDP DNS TCP连接的建立与终止 TCP流量控制 TCP拥塞控制 0 前言 本文整理了一些TCP/I ...

  8. Java中final,finally和finalize区别

    Day11_SHJavaTraing_4-18-2017 Java中final,finally和finalize区别 1.final—修饰符(关键字) ①final修饰类,表示该类不可被继承 ②fin ...

  9. 07--c++类的构造函数详解

    c++类的构造函数详解 c++构造函数的知识在各种c++教材上已有介绍,不过初学者往往不太注意观察和总结其中各种构造函数的特点和用法,故在此我根据自己的c++编程经验总结了一下c++中各种构造函数的特 ...

  10. wx小程序开发 1:小程序代码构成

    官网学习地址:https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/introduction.html 1: 2:待续.. ...