iOS 裁剪圆形图像并显示(类似于微信头像)

原创 2017年06月26日 12:38:45

  本文主要讲解如何从照片库选择一张照片后将其裁剪成圆形头像并显示,类似于微信头像那种模式。

  本文的方法也适用于当时拍照获取的图像,方法类似,所以不再赘述。

  本文主要是在iOS 10环境下使用,此时如果要使用使用系统照片库、照相机等功能需要授权,授权方法如下:

  右键点击工程目录中的“Info.plist文件——>Open As ——>Source Code”,打开复制以下你在应用中使用的隐私权限设置(描述自己修改):

    <key>NSVideoSubscriberAccountUsageDescription</key>
    <string></string>
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>蓝牙权限</string>
    <key>NSSpeechRecognitionUsageDescription</key>
    <string>语音识别权限</string>
    <key>NSSiriUsageDescription</key>
    <string>Siri权限</string>
    <key>NSRemindersUsageDescription</key>
    <string></string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>相册权限</string>
    <key>kTCCServiceMediaLibrary</key>
    <string></string>
    <key>NSMotionUsageDescription</key>
    <string>运动权限</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>麦克风权限</string>
    <key>NSAppleMusicUsageDescription</key>
    <string>音乐权限</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>地理位置权限</string>
    <key>NSLocationUsageDescription</key>
    <string>地理位置权限</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>地理位置权限</string>
    <key>NSHomeKitUsageDescription</key>
    <string></string>
    <key>NSHealthUpdateUsageDescription</key>
    <string>健康权限</string>
    <key>NSHealthShareUsageDescription</key>
    <string>健康权限</string>
    <key>NSContactsUsageDescription</key>
    <string>通讯录权限</string>
    <key>NSCameraUsageDescription</key>
    <string>摄像头权限</string>
    <key>NSCalendarsUsageDescription</key>
    <string>日历权限</string>

  下面,正式进入本文要实现的功能的代码编写。

1. 使用Xcode的storyboard创建一个button和一个imageView

  创建后的效果如下图1所示。其中,imageView的尺寸影响最终显示的效果尺寸,请根据实际情况设置。

图1

2. 创建一个UIImage的类别(Category)

  创建新文件,选择“Objective-C File”,如下图2所示:

图2

在弹出的如图3所示的对话框中,“File”写入类别的名称(本例中是DY),“File Type”选择Category,“Class”选择UIImage。然后点击“Next”按钮,将新文件保存。

图3

3. 编写类别中的代码

UIImage+DY.h文件中


#import <UIKit/UIKit.h>

@interface UIImage (DY)

+ (instancetype)circleOldImage:(UIImage *)originalImage borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor;

@end

UIImage+DY.m文件中

#import "UIImage+DY.h"

@implementation UIImage (DY)

+ (instancetype)circleOldImage:(UIImage *)originalImage borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor
{
    // 1.加载原图
    UIImage *oldImage = originalImage;

    // 2.开启上下文
    CGFloat imageW = oldImage.size.width + 2 * borderWidth;
    CGFloat imageH = oldImage.size.height + 2 * borderWidth;
    CGSize imageSize = CGSizeMake(imageW, imageH);
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);

    // 3.取得当前的上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // 4.画边框(大圆)
    [borderColor set];
    CGFloat bigRadius = imageW * 0.5; // 大圆半径
    CGFloat centerX = bigRadius; // 圆心
    CGFloat centerY = bigRadius;
    CGContextAddArc(ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0);
    CGContextFillPath(ctx); // 画圆

    // 5.小圆
    CGFloat smallRadius = bigRadius - borderWidth;
    CGContextAddArc(ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0);
    // 裁剪(后面画的东西才会受裁剪的影响)
    CGContextClip(ctx);

    // 6.画图
    [oldImage drawInRect:CGRectMake(borderWidth, borderWidth, oldImage.size.width, oldImage.size.height)];

    // 7.取图
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    // 8.结束上下文
    UIGraphicsEndImageContext();

    return newImage;
}


@end

+(instancetype)circleOldImage:(UIImage )originalImage borderWidth:(CGFloat)borderWidth borderColor:(UIColor )borderColor方法的说明:
1. 这是一个类方法,最终返回的是一个UIImage的类;
2. 方法中originalImage参数指的是从照片库或者拍照后选中的照片(可能是经过系统裁剪的);
3. 方法中borderWidth参数指的是最终显示的圆形图像的边框的宽度,可以可以根据自己的需要设置宽度;
4. 方法中的borderColor参数指的是最终显示的圆形图像的边框的颜色,可以可以根据自己的需要设置颜色。

4. 实现裁剪成圆形图像并显示

ViewController.h文件

#import <UIKit/UIKit.h>
#import "UIImage+DY.h"  //加载类别

@interface ViewController : UIViewController<UINavigationControllerDelegate, UIImagePickerControllerDelegate>  //一定要添加这两个Delegate


@property (strong, nonatomic) UIImagePickerController *imagePickerController;

- (IBAction)btnPressed:(id)sender;

@property (strong, nonatomic) IBOutlet UIImageView *ablumImageView;


@end

ViewController.m文件

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction)btnPressed:(id)sender {

    if([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary]) {

        //首先判断是否支持照片库,这个方法中的参数要和_imagePickerController.sourceType的值保持一致

        //如果支持

        _imagePickerController = [[UIImagePickerController alloc]init];

        _imagePickerController.view.backgroundColor = [UIColor orangeColor];
        _imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        _imagePickerController.delegate = self;
        _imagePickerController.allowsEditing = YES;  //该参数默认是NO,建议设置为YES,否则裁剪成圆形图片的方法将获取到的是椭圆形的图片,与你的预想大相径庭

        [self presentViewController:_imagePickerController animated:YES completion:nil];

    }


}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    _ablumImageView.image = [UIImage circleOldImage:[info objectForKey:UIImagePickerControllerEditedImage] borderWidth:30.0f borderColor:[UIColor orangeColor]];  
    //该方法中Info的Key值“UIImagePickerControllerEditedImage”表示的是选择裁剪后的图片,如果使用这个Key值,则_imagePickerController.allowsEditing的值需要设置为YES。

    //如果_imagePickerController.allowsEditing的值设置的NO,则这个Key的值应该设置为UIImagePickerControllerOriginalImage

    /*
    info中的Key的值有如下几个:

    NSString *const  UIImagePickerControllerMediaType ;指定用户选择的媒体类型(文章最后进行扩展)
NSString *const  UIImagePickerControllerOriginalImage ;原始图片
NSString *const  UIImagePickerControllerEditedImage ;修改后的图片
NSString *const  UIImagePickerControllerCropRect ;裁剪尺寸
NSString *const  UIImagePickerControllerMediaURL ;媒体的URL
NSString *const  UIImagePickerControllerReferenceURL ;原件的URL
NSString *const  UIImagePickerControllerMediaMetadata;当来数据来源是照相机的时候这个值才有效

    */


    [self dismissViewControllerAnimated:YES completion:nil];

}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{


    [self dismissViewControllerAnimated:YES completion:nil];

}

@end

本文原发表于我的简书专题中。

iOS 相机拍照、相册获取照片(仿微信) 一一 拍照、图片裁剪

iOS自定义相机拍照(仿微信),图片方向调整,图片裁剪
  • a44496913
  • a44496913
  • 2017年06月08日 22:38
  • 2354

iOS从相册选择图片并裁剪,可用于上传头像

iOS从相册选择图片并裁剪前言笔者最近接了一个任务,是从手机相册选择图片并裁剪后上传。于是在裁剪的这一块,我用了VPImageCropper。从相册获取图片,我一开始看的是TZImagePickerC...
  • Bloody_Leaves
  • Bloody_Leaves
  • 2016年09月03日 10:40
  • 4246

iOS 调取本地相册/相机,剪裁图片进行头像上传

打开本地相册或打开本地相机拍照,获取图片裁剪图片,上传图片加入头文件#import #import #import 全部变量NSString*THE_IMG_PATH; NSString *_im...
  • liyiyiSmile
  • liyiyiSmile
  • 2015年09月15日 16:30
  • 4457

iOS 头像裁剪上传

打开本地相册或打开本地相机拍照,获取图片裁剪图片,上传图片 加入头文件 #import #import #import 123123 全部变量 NSString*THE_IMG_PATH; NSS...
  • LiqunZhang
  • LiqunZhang
  • 2017年03月22日 10:23
  • 480

iOS 上传头像 裁剪

1:首先几个必须得返回值//相机是否可用 - (BOOL) isCameraAvailable{ return [UIImagePickerController isSourceTypeAva...
  • Akries
  • Akries
  • 2015年05月05日 21:03
  • 1643

仿微信通过拍照或者本地图片裁剪完美更换头像

  • 2015年11月18日 09:38
  • 7.97MB
  • 下载

iOS裁切图片(圆头像的实现)

裁切图片(圆头像的实现)1.还是那几个步骤2.步骤详细在代码里- (void)viewDidLoad { [super viewDidLoad]; //加载图片 UIImage...
  • u011252234
  • u011252234
  • 2016年06月28日 09:42
  • 1204

仿微信头像剪切

来个动图: 裁剪效果其实就是图片在底部,上层一个视图重叠在上面,这里参考的是洪洋大神的仿微信头像篇,文章说的相当清楚了,我只是简洁的删改一点,看裁剪这个页面: 两个View重叠,就有了这个效果...
  • hedong_77
  • hedong_77
  • 2017年01月18日 16:23
  • 944

仿微信通过拍照、本地图片然后裁剪完美更换头像

其实更换头像这个功能是个老梗了,写的人也很多,但是我没有看见过特别让我满意的,没办法,只能自己搞了。这里面我只说难点吧,最后的会附上完整的代码。这里面涉及到的功能有哪些呢? 大概有:拍照 、扫描本地...
  • u011625768
  • u011625768
  • 2015年11月18日 10:26
  • 2851

cocos2dx 剪切圆形头像

项目需求,要把矩形的头像(或任意图片)剪切成圆形的。然后在网上找到一些方法,并做了简单修改。这里做下记录。 cc.exports.display = display or {} function ...
  • keven418440201
  • keven418440201
  • 2016年11月24日 18:05
  • 1729
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS 裁剪圆形图像并显示(类似于微信头像)
举报原因:
原因补充:

(最多只允许输入30个字)