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