本文主要講解如何從照片庫選擇一張照片後将其裁剪成圓形頭像并顯示,類似于微信頭像那種模式。
本文的方法也适用于當時拍照擷取的圖像,方法類似,是以不再贅述。
本文主要是在iOS 10環境下使用,此時如果要使用使用系統照片庫、照相機等功能需要授權,授權方法如下:
右鍵點選工程目錄中的“Info.plist檔案——>Open As ——>Source Code”,打開複制以下你在應用中使用的隐私權限設定(描述自己修改):
NSVideoSubscriberAccountUsageDescription
NSBluetoothPeripheralUsageDescription
藍牙權限
NSSpeechRecognitionUsageDescription
語音識别權限
NSSiriUsageDescription
Siri權限
NSRemindersUsageDescription
NSPhotoLibraryUsageDescription
相冊權限
kTCCServiceMediaLibrary
NSMotionUsageDescription
運動權限
NSMicrophoneUsageDescription
麥克風權限
NSAppleMusicUsageDescription
音樂權限
NSLocationWhenInUseUsageDescription
地理位置權限
NSLocationAlwaysAndWhenInUseUsageDescription
地理位置權限
NSLocationUsageDescription
地理位置權限
NSLocationAlwaysUsageDescription
地理位置權限
NSHomeKitUsageDescription
NSHealthUpdateUsageDescription
健康權限
NSHealthShareUsageDescription
健康權限
NSContactsUsageDescription
通訊錄權限
NSCameraUsageDescription
攝像頭權限
NSCalendarsUsageDescription
月曆權限
下面,正式進入本文要實作的功能的代碼編寫。
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
@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方法的說明:
這是一個類方法,最終傳回的是一個UIImage的類;
方法中originalImage參數指的是從照片庫或者拍照後選中的照片(可能是經過系統裁剪的);
方法中borderWidth參數指的是最終顯示的圓形圖像的邊框的寬度,可以可以根據自己的需要設定寬度;
方法中的borderColor參數指的是最終顯示的圓形圖像的邊框的顔色,可以可以根據自己的需要設定顔色。
4. 實作裁剪成圓形圖像并顯示
ViewController.h檔案
#import
#import "UIImage+DY.h" //加載類别
@interface ViewController : UIViewController //一定要添加這兩個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
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:nil];
}
@end