UIImage+CTFCrop.h
@interface UIImage (CTFCrop) - (UIImage *)resizeImageWithSize:(CGSize)newSize; - (UIImage *)ovalClip; @end
UIImage+CTFCrop.m
@implementation UIImage (CTFCrop)
- (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;
}
@end
CTFCropImageVC.h
typedef void(^CropedImageBlock)(UIImage *cropedImage); @protocol CropImageDelegate <NSObject> - (void)cropImageDidFinishedWithImage:(UIImage *)image; @end @interface CTFCropImageVC : BaseViewController @property (nonatomic, weak) id <CropImageDelegate> delegate; @property (nonatomic, assign) BOOL ovalClip;//圆形裁剪,默认开启; - (instancetype)initWithImage:(UIImage *)originalImage delegate:(id)delegate; @property (nonatomic, copy) CropedImageBlock cropedImageBlock; @end
CTFCropImageVC.m
#import "UIImage+CTFCrop.h"
#import "AppDelegate.h"
@interface CTFCropImageVC () <UIScrollViewDelegate>
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIImage *originalImage;
@end
@implementation CTFCropImageVC
- (instancetype)initWithImage:(UIImage *)originalImage delegate:(id)delegate {
if (self = [super init]) {
self.originalImage = originalImage;
self.delegate = delegate;
self.ovalClip = YES;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.isHiddenNavBar = YES;
self.view.backgroundColor = [UIColor blackColor];
self.automaticallyAdjustsScrollViewInsets = NO;
CGFloat top_height = 168;
CGFloat width_cropView = kScreen_Width - 39 - 39;
CGFloat height_cropView = kScreen_Width - 39 - 39;
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(39, top_height, width_cropView, height_cropView)];
self.scrollView.bouncesZoom = YES;
self.scrollView.minimumZoomScale = 1;
self.scrollView.maximumZoomScale = 3;
self.scrollView.zoomScale = 1;
self.scrollView.delegate = self;
self.scrollView.layer.masksToBounds = NO;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.layer.borderWidth = 1.5;
self.scrollView.layer.borderColor = [UIColor whiteColor].CGColor;
if (self.ovalClip) {
self.scrollView.layer.cornerRadius = width_cropView/2.0;
}
self.view.layer.masksToBounds = YES;
if (self.originalImage) {
self.imageView = [[UIImageView alloc] initWithImage:self.originalImage];
CGFloat img_width = 0.f;
CGFloat img_height = 0.f;
CGFloat img_x= 0.f;
CGFloat img_y= 0.f;
if (self.originalImage.size.height > self.originalImage.size.width) {//高度 大于 宽度
img_width = width_cropView;
img_height = self.originalImage.size.height * (img_width/self.originalImage.size.width);
img_x= 0.f;
img_y= (img_height - height_cropView)/2.0;
}else if (self.originalImage.size.height < self.originalImage.size.width) {//宽度 大于 高度
img_height = height_cropView;
img_width = self.originalImage.size.width * (img_height/self.originalImage.size.height);
img_x= (img_width - width_cropView)/2.0;
img_y= 0.f;
}else {//正方形
img_height = height_cropView;
img_width = width_cropView;
img_x= 0.f;
img_y= 0.f;
}
self.imageView.frame = CGRectMake(0, 0, img_width, img_height);
self.imageView.userInteractionEnabled = YES;
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = CGSizeMake(img_width, img_height);
self.scrollView.contentOffset = CGPointMake(img_x, img_y);
[self.view addSubview:self.scrollView];
}
[self userInterface];
//
UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
[cancelBtn addTarget:self action:@selector(cancelBtnAction) forControlEvents:UIControlEventTouchUpInside];
[cancelBtn setTitleColor:UIColorFromHEX(0xFFFFFF) forState:UIControlStateNormal];
cancelBtn.titleLabel.font = [UIFont systemFontOfSize:18];
cancelBtn.backgroundColor = [UIColor clearColor];
[self.view addSubview:cancelBtn];
[cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view.mas_left).offset(76);
make.bottom.mas_equalTo(self.view.mas_bottom).offset(-36);
}];
//
UIButton *sureBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[sureBtn setTitle:@"确定" forState:UIControlStateNormal];
[sureBtn addTarget:self action:@selector(sureBtnAction) forControlEvents:UIControlEventTouchUpInside];
[sureBtn setTitleColor:UIColorFromHEX(0xFFFFFF) forState:UIControlStateNormal];
sureBtn.titleLabel.font = [UIFont systemFontOfSize:18];
sureBtn.layer.masksToBounds = YES;
sureBtn.layer.backgroundColor = UIColorFromHEX(0xFF6885).CGColor;
sureBtn.layer.cornerRadius = 20;
[self.view addSubview:sureBtn];
[sureBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(self.view.mas_right).offset(-55);
make.bottom.mas_equalTo(self.view.mas_bottom).offset(-28);
make.size.mas_equalTo(CGSizeMake(74, 40));
}];
}
- (void)cancelBtnAction {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)sureBtnAction {
UIImage *cropImage = [self cropImage];
if (self.cropedImageBlock) {
self.cropedImageBlock(cropImage);
}
[self.navigationController popViewControllerAnimated:YES];
}
- (void)userInterface {
CGRect cropframe = self.scrollView.frame;
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds cornerRadius:0];
UIBezierPath * cropPath = [UIBezierPath bezierPathWithRoundedRect:cropframe cornerRadius:0];
if (self.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;
//填充规则
layer.fillRule = kCAFillRuleEvenOdd;
layer.path = path.CGPath;
[self.view.layer addSublayer:layer];
}
#pragma mark -- UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
//调整位置
[self centerContent];
}
- (void)centerContent {
CGRect imageViewFrame = self.imageView.frame;
CGRect scrollBounds = CGRectMake(0, 0, kScreen_Width - 39 - 39, kScreen_Width - 39 - 39);
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;
}
self.imageView.frame = imageViewFrame;
}
- (UIImage *)cropImage {
CGPoint offset = self.scrollView.contentOffset;
CGFloat zoom = self.imageView.frame.size.width / self.originalImage.size.width;
CGFloat width_scroll = self.scrollView.frame.size.width;
CGFloat height_scroll = self.scrollView.frame.size.height;
CGRect rec = CGRectMake(fabs(offset.x)/zoom, fabs(offset.y)/zoom, width_scroll/zoom, height_scroll/zoom);
UIImage * image = [self cropImage:self.originalImage toRect:rec];
return image;
}
- (UIImage *)cropImage:(UIImage*)image toRect:(CGRect)rect {
CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) {
return deg / 180.0f * (CGFloat) M_PI;
};
CGAffineTransform rectTransform;
switch (image.imageOrientation) {
case UIImageOrientationLeft:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height);
break;
case UIImageOrientationRight:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0);
break;
case UIImageOrientationDown:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height);
break;
default:
rectTransform = CGAffineTransformIdentity;
};
// adjust the transformation scale based on the image scale
rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale);
// apply the transformation to the rect to create a new, shifted rect
CGRect transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform);
// use the rect to crop the image
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare);
// create a new UIImage and set the scale and orientation appropriately
UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
// memory cleanup
CGImageRelease(imageRef);
return result;
}
@end