類似微信頭像選擇裁剪功能 ,設(shè)置UIImagePickerController的allowsEditing屬性為YES即可實(shí)現(xiàn)翁脆,但如何自己實(shí)現(xiàn)此功能呢眷蚓?如何實(shí)現(xiàn)類似系統(tǒng)聯(lián)系人圓形頭像裁剪選取呢?
如圖:
圖片要支持縮放和拖拽反番,首先想到scrollView沙热,具體實(shí)現(xiàn)方法如下:
//CropImageController.h
@protocol CropImageDelegate <NSObject>
- (void)cropImageDidFinishedWithImage:(UIImage *)image;
@end
@interface CropImageController : UIViewController
@property (nonatomic, weak) id <CropImageDelegate> delegate;
//圓形裁剪,默認(rèn)NO;
@property (nonatomic, assign) BOOL ovalClip;
- (instancetype)initWithImage:(UIImage *)originalImage delegate:(id)delegate;
@end
在viewDidLoad初始化scrollView,設(shè)置frame為裁剪框大小罢缸,若需要超出邊界線內(nèi)容仍然可以顯示篙贸,設(shè)置其layer屬性masksToBounds即可
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blackColor];
self.automaticallyAdjustsScrollViewInsets = NO;
CGFloat height = (ScreenHeight - ScreenWidth)/2.0;
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, height ,ScreenWidth,ScreenWidth)];
_scrollView.bouncesZoom = YES;
_scrollView.minimumZoomScale = 1;
_scrollView.maximumZoomScale = 3;
_scrollView.zoomScale = 1;
_scrollView.delegate = self;
_scrollView.layer.masksToBounds = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.layer.borderWidth = 1.5;
_scrollView.layer.borderColor = [UIColor whiteColor].CGColor;
if (_ovalClip) {
_scrollView.layer.cornerRadius = ScreenWidth/2.0;
}
self.view.layer.masksToBounds = YES;
if (_originalImage) {
_imageView = [[UIImageView alloc] initWithImage:_originalImage];
CGFloat img_width = ScreenWidth;
CGFloat img_height = _originalImage.size.height * (img_width/_originalImage.size.width);
CGFloat img_y= (img_height - self.view.bounds.size.width)/2.0;
_imageView.frame = CGRectMake(0,0, img_width, img_height);
_imageView.userInteractionEnabled = YES;
[_scrollView addSubview:_imageView];
_scrollView.contentSize = CGSizeMake(img_width, img_height);
_scrollView.contentOffset = CGPointMake(0, img_y);
[self.view addSubview:_scrollView];
}
[self userInterface];
}
設(shè)置self.view中間鏤空效果:
- (void)userInterface {
CGRect cropframe = _scrollView.frame;
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds cornerRadius:0];
UIBezierPath * cropPath = [UIBezierPath bezierPathWithRoundedRect:cropframe cornerRadius:0];
if (_ovalClip) {
cropPath = [UIBezierPath bezierPathWithOvalInRect:cropframe];
}
[path appendPath:cropPath];
CAShapeLayer * layer = [[CAShapeLayer alloc] init];
layer.fillColor = [UIColor colorWithRed:.0 green:.0 blue:.0 alpha:0.5].CGColor;
//填充規(guī)則
layer.fillRule=kCAFillRuleEvenOdd;
layer.path = path.CGPath;
[self.view.layer addSublayer:layer];
}
UIScrollViewDelegate,縮放和滑動(dòng)過程中調(diào)整內(nèi)容視圖大小:
#pragma mark -- UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
//調(diào)整位置
[self centerContent];
}
- (void)centerContent {
CGRect imageViewFrame = _imageView.frame;
CGRect scrollBounds = CGRectMake(0, 0, ScreenWidth, ScreenWidth);
if (imageViewFrame.size.height > scrollBounds.size.height) {
imageViewFrame.origin.y = 0.0f;
}else {
imageViewFrame.origin.y = (scrollBounds.size.height - imageViewFrame.size.height) / 2.0;
}
if (imageViewFrame.size.width < scrollBounds.size.width) {
imageViewFrame.origin.x = (scrollBounds.size.width - imageViewFrame.size.width) /2.0;
}else {
imageViewFrame.origin.x = 0.0f;
}
_imageView.frame = imageViewFrame;
}
調(diào)整位置確定選取圖片時(shí)候枫疆,可根據(jù)當(dāng)前ScrollView的contentOffset和縮放倍數(shù)確定具體裁剪位置:
- (UIImage *)cropImage {
CGPoint offset = _scrollView.contentOffset;
//圖片縮放比例
CGFloat zoom = _imageView.frame.size.width/_originalImage.size.width;
//視網(wǎng)膜屏設(shè)備像素相關(guān)
zoom = zoom / [UIScreen mainScreen].scale;
CGFloat width = _scrollView.frame.size.width;
CGFloat height = _scrollView.frame.size.height;
if (_imageView.frame.size.height < _scrollView.frame.size.height) {//太胖了,取中間部分
offset = CGPointMake(offset.x + (width - _imageView.frame.size.height)/2.0, 0);
width = height = _imageView.frame.size.height;
}
CGRect rec = CGRectMake(offset.x/zoom, offset.y/zoom,width/zoom,height/zoom);
CGImageRef imageRef =CGImageCreateWithImageInRect([_originalImage CGImage],rec);
UIImage * image = [[UIImage alloc]initWithCGImage:imageRef];
CGImageRelease(imageRef);
if (_ovalClip) {
image = [image ovalClip];
}
return image;
}
UIImage分類(圖片指定尺寸縮放和圓形裁剪):
//UIImage+Crop.m
- (UIImage *)resizeImageWithSize:(CGSize)newSize {
CGFloat newWidth = newSize.width;
CGFloat newHeight = newSize.height;
float width = self.size.width;
float height = self.size.height;
if (width != newWidth || height != newHeight) {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(newWidth, newHeight), YES, [UIScreen mainScreen].scale);
[self drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *resized = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resized;
}
return self;
}
- (UIImage *)ovalClip {
CGSize size = self.size;
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
[path addClip];
[self drawAtPoint:CGPointZero];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}