iOS开发——定制圆形头像与照相机图库的使用

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

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

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

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

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

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

实现代码例如以下:

- (void)setCirclePhoto{
//avatarImage是图片控件;
  [self.avatarImage.layer setCornerRadius:CGRectGetHeight([self.avatarImage bounds]) / 2];
  self.avatarImage.layer.masksToBounds = true;

  //能够依据需求设置边框宽度、颜色
  self.avatarImage.layer.borderWidth = 1;
  self.avatarImage.layer.borderColor = [[UIColor blackColor] CGColor];
  //设置图片;
  self.avatarImage.layer.contents = (id)[[UIImage imageNamed:@"avatar.png"] CGImage];

}

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

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

- (IBAction)selectPhoto:(id)sender {

  if ([self.imagePickerPopover isPopoverVisible]) {
    [self.imagePickerPopover dismissPopoverAnimated:YES];
    self.imagePickerPopover = nil;
    return;
  }

  UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
  imagePicker.editing = YES;

  //假设设备支持相机。就使用拍照技术
  //否则让用户从照片库中选择照片
  if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
  {
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
  }
  else{
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  }

  imagePicker.delegate = self;

  //同意编辑图片
  imagePicker.allowsEditing = YES;

  //创建UIPopoverController对象前先检查当前设备是不是ipad
  if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
    self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
    self.imagePickerPopover.delegate = self;
    [self.imagePickerPopover presentPopoverFromBarButtonItem:sender
                                    permittedArrowDirections:UIPopoverArrowDirectionAny
                                                    animated:YES];
  }
  else
  {
    [self presentViewController:imagePicker animated:YES completion:nil];
  }
}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
  //通过info字典获取选择的照片
  UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];

  //以itemKey为键,将照片存入ImageStore对象中
  [[MyImageStore sharedStore] setImage:image forKey:@"CYFStore"];

  //将照片放入UIImageView对象
  self.avatarImage.image = image;

  //推断UIPopoverController对象是否存在
  if (self.imagePickerPopover) {
    [self.imagePickerPopover dismissPopoverAnimated:YES];
    self.imagePickerPopover = nil;
  }
  else
  {
    //关闭以模态形式显示的UIImagePickerController
    [self dismissViewControllerAnimated:YES completion:nil];
  }
}

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

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

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

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

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

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

@property (strong, nonatomic) UIPopoverController *imagePickerPopover;

UIPopoverController对象用来打开照相机。

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

+(instancetype)sharedStore
{
  static MyImageStore *instance = nil;

  //确保多线程中仅仅创建一次对象,线程安全的单例
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [[self alloc] initPrivate];
  });

  return instance;
}

-(instancetype)initPrivate
{
  self = [super init];
  if (self) {
    _dictionary = [[NSMutableDictionary alloc] init];

    //注冊为低内存通知的观察者
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self
           selector:@selector(clearCaches:)
               name:UIApplicationDidReceiveMemoryWarningNotification
             object:nil];
  }
  return self;
}

-(void)setImage:(UIImage *)image forKey:(NSString *)key
{
  [self.dictionary setObject:image forKey:key];

  //获取保存图片的全路径
  NSString *path = [self imagePathForKey:key];

  //从图片提取JPEG格式的数据,第二个參数为图片压缩參数
  NSData *data = UIImageJPEGRepresentation(image, 0.5);
  //以PNG格式提取图片数据
  //NSData *data = UIImagePNGRepresentation(image);

  //将图片数据写入文件
  [data writeToFile:path atomically:YES];
}

-(UIImage *)imageForKey:(NSString *)key
{
  //return [self.dictionary objectForKey:key];
  UIImage *image = [self.dictionary objectForKey:key];
  if (!image) {
    NSString *path = [self imagePathForKey:key];

    image = [UIImage imageWithContentsOfFile:path];
    if (image) {
      [self.dictionary setObject:image forKey:key];
    }
    else
    {
      NSLog(@"Error: unable to find %@", [self imagePathForKey:key]);
    }
  }
  return image;
}

-(NSString *)imagePathForKey:(NSString *)key
{
  NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentDirectory = [documentDirectories firstObject];
  return [documentDirectory stringByAppendingPathComponent:key];
}

-(void)clearCaches:(NSNotification *)n
{
  NSLog(@"Flushing %ld images out of the cache", (unsigned long)[self.dictionary count]);
  [self.dictionary removeAllObjects];
}

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

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

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

博客更新:

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

 imagePicker.allowsEditing = false;

同一时候把:

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

改动为:

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

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

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

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

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

应用优化与更新:

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

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

- (IBAction)selectPhoto:(id)sender {

  if ([self.imagePickerPopover isPopoverVisible]) {
    [self.imagePickerPopover dismissPopoverAnimated:YES];
    self.imagePickerPopover = nil;
    return;
  }

  UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
  imagePicker.editing = YES;
  imagePicker.delegate = self;

  /*
   假设这里allowsEditing设置为false。则以下的UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];
   应该改为: UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
   也就是改为原图像。而不是编辑后的图像。

*/

  //同意编辑图片
  imagePicker.allowsEditing = YES;
  /*
   这里以弹出选择框的形式让用户选择是打开照相机还是图库
   */

  //初始化提示框。
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请选择打开方式" message:nil preferredStyle:  UIAlertControllerStyleActionSheet];

  [alert addAction:[UIAlertAction actionWithTitle:@"照相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;//设置为照相机打开;

    //创建UIPopoverController对象前先检查当前设备是不是ipad
    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
      self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
      self.imagePickerPopover.delegate = self;
      [self.imagePickerPopover presentPopoverFromBarButtonItem:sender
                                      permittedArrowDirections:UIPopoverArrowDirectionAny
                                                      animated:YES];
    }
    else{
      [self presentViewController:imagePicker animated:YES completion:nil];

    }
  }]];

  [alert addAction:[UIAlertAction actionWithTitle:@"相冊" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//设置为图库打开。

    //创建UIPopoverController对象前先检查当前设备是不是ipad
    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
      self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
      self.imagePickerPopover.delegate = self;
      [self.imagePickerPopover presentPopoverFromBarButtonItem:sender
                                      permittedArrowDirections:UIPopoverArrowDirectionAny
                                                      animated:YES];
    }
    else{
      [self presentViewController:imagePicker animated:YES completion:nil];
    }
  }]];

  [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
    //取消;
  }]];

  //弹出提示框;
  [self presentViewController:alert animated:true completion:nil];
}

实现效果例如以下:

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

欢迎大家訪问!

时间: 2024-10-06 12:41:41

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

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

iOS开发-定制多样式二维码 二维码/条形码是按照某种特定的几何图形按一定规律在平台(一维/二维方向上)分布的黑白相间的图形纪录符号信息.使用若干个与二进制对应的几何形体来表示文字数值信息. 最常见的二维码功能包括信息获取.网站跳转.电商交易.手机支付等等,其拥有密度小.信息容量大.容错能力强.成本低.制作难度低等优点.在移动开发中,二维码的地位也越来越重要,掌握二维码的基本操作是重要的本领之一. 在iOS7之后,苹果自身集成了二维码的生成和读取功能.生成二维码包括以下步骤 1.导入CoreIm

IOS开发-设置头像(圆形)

app 头像设置,做成圆形的越来越多.而实现并不是很难,但是图像处理好很重要. <span style="font-size:14px;">UIImageView *imgV = [[UIImageView alloc]initWithFrame:CGRectMake(200,100 , 100, 100)]; UIImage *image = [UIImage imageNamed:@"1"]; imgV.image = image; [imgV.la

iOS中裁剪圆形头像

- (void)clipImage { // 0.加载图片 UIImage *image = [UIImage imageNamed:@"阿狸头像"]; // 1.开启位图上下文,跟图片尺寸一样大 UIGraphicsBeginImageContextWithOptions(image.size, NO, 0); // 2.设置圆形裁剪区域,正切与图片 // 2.1创建圆形的路径 UIBezierPath *path = [UIBezierPath bezierPathWithOval

【iOS开发每日小笔记(十)】自制带圆框的头像 利用在CALayer设置“寄宿图”

这篇文章是我的[iOS开发每日小笔记]系列中的一片,记录的是今天在开发工作中遇到的,可以用很短的文章或很小的demo演示解释出来的小心得小技巧.它们可能会给用户体验.代码效率得到一些提升,或是之前自己没有接触过的技术,很开心的学到了,放在这里得瑟一下.90%的作用是帮助自己回顾.记忆.复习. 在上一篇文章中,我详细地回顾.复习了Core Graphics框架中利用Quartz 2D来绘制各种各样的图形,其实这些绘图就是绘制到了UIView的CALayer层上.这次,受到另一篇博文(http://

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

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

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

Android项目开发中经常会遇见需要实现圆角或者圆形的图片功能,如果仅仅使用系统自带的ImageView控件显然无法实现此功能,所以通过系列文章的形式由简到繁全方位的介绍一下此功能的实现,巩固一下自身的学习,同时,和广大网友交流分享 本项目源码下载地址:链接:http://pan.baidu.com/s/1sljdvtF 密码:xj85 首先看效果图 首先看一下CircleImageView的主要流程 1. 首先通过setImageXxx()方法设置图片Bitmap: 2. 进入构造函数Cir

从零开始学ios开发(十二):Table Views(中)UITableViewCell定制

我们继续学习Table View的内容,这次主要是针对UITableViewCell,在前一篇的例子中我们已经使用过UITableViewCell,一个默认的UITableViewCell包含imageView.textLabel.detailTextLabel等属性,但是很多时候这些默认的属性并不能满足需要,其实更多的时候我们想自己制定UITableViewCell的内容,这篇学习的就是制定自己的UITableViewCell. UITableViewCell继承自UIView,因此它可以加载

iOS 画圆形头像

demo下载地址:http://pan.baidu.com/s/1mgBf6YG _logoImageView.image = [self getEllipseImageWithImage:[UIImage imageNamed:@"1_wsq724439564.jpg"]]; -(UIImage*)getEllipseImageWithImage:(UIImage*)originImage { CGFloat padding = 5;//圆形图像距离图像的边距 UIColor* ep

ios 开发选取头像,图片库,相机,裁取图片

需要遵守的代理协议:UIActionSheetDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate @property (nonatomic, strong) UIActionSheet *avatarActionSheet; 第一步:点击头像cell需要做的事情 [self.avatarActionSheet showInView:self.view]; 第二步: #pragma mark - 点击头像