- 核心代码:
如果要将裁剪后的上下文渲染到控件上,必须设置要将其到控件的layer图层上,调用某个view的layer的renderInContext:方法即可
[self.imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
1、 裁剪步骤分析
1、开启位图上下文,
UIGraphicsBeginImageContextWithOptions(上下文尺寸
, NO, 0);
2、设置裁剪区域
* 通过 UIBezierPath方式
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.cover.frame];
[path addClip]; // 设置裁剪区域
3、从上下文中获得裁剪图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
4、如果要将裁剪后的上下文渲染到控件上,必须设置要将其到控件的layer图层上
[self.imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
5、关闭位图上下文
UIGraphicsEndImageContext();
2、实现
- 1.自定义ClipImageView,继承UIImageView
// .h文件
#import <UIKit/UIKit.h>
@interface ClipImageView : UIImageView
@end
// .m实现文件
#import "ClipImageView.h"
#define kToorBarW 100
#define kToorBarH 40
@interface ClipImageView ()
@property (nonatomic, weak) UIToolbar *toolBar;
@property (nonatomic, weak) UIView *cover;
@property (nonatomic, assign) CGPoint beginP;
@property (nonatomic, strong) UIImage *oraginImage;
@end
@implementation ClipImageView
- (void)addGesture{
NSLog(@"%s", __func__);
/**
1、给imageView添加拖拽手势识别
*/
UIPanGestureRecognizer *panG = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(imageVPanAction:)];
[self addGestureRecognizer:panG];
self.userInteractionEnabled = YES; // 允许用户交互,默认是不可以的,手动设置需要
self.clipsToBounds = YES;
if (self.image != nil) {
self.oraginImage = self.image;
}
}
// 代码创建
- (nonnull instancetype)initWithFrame:(CGRect)frame{
NSLog(@"%s", __func__);
if (self = [super initWithFrame:frame]) {
[self addGesture];
}
return self;
}
// xib初始化
- (void)awakeFromNib{
[super awakeFromNib];
NSLog(@"%s", __func__);
[self addGesture];
}
/**
* 布局
*/
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"%s", __func__);
[self addGesture];
}
- (UIToolbar *)toolBar{
if (_toolBar == nil) {
/**
1、添加工具条
*/
// UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(kMargin, 0, self.view.frame.size.width - 2*kMargin, 60)];
UIToolbar *toolBar = [[UIToolbar alloc] init];
toolBar.backgroundColor = [UIColor orangeColor];
UIBarButtonItem *btnItem1 = [[UIBarButtonItem alloc] initWithTitle:@"裁剪" style:UIBarButtonItemStylePlain target:self action:@selector(clipAction)];
UIBarButtonItem *btnItem2 = [[UIBarButtonItem alloc] initWithTitle:@"撤销" style:UIBarButtonItemStylePlain target:self action:@selector(doAgainClip)];
[toolBar setItems:@[btnItem1, btnItem2] animated:YES];
_toolBar = toolBar;
[self addSubview:toolBar];
}
return _toolBar;
}
/**
* 懒加载,设置遮罩视图
*/
- (UIView *)cover{
if (_cover == nil) {
UIView *cover = [[UIView alloc] init];
_cover = cover;
_cover.backgroundColor = [UIColor colorWithRed:155 green:0 blue:0 alpha:0.3];
[self addSubview:cover];
// 给cover添加拖拽手势
UIPanGestureRecognizer *coverPanG = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(coverPanAction:)];
[self.cover addGestureRecognizer:coverPanG];
self.cover.hidden = YES;
self.toolBar.hidden = YES;
}
return _cover;
}
/**
* 实现imageView的拖拽手势调用方法
* 1、拖拽时,设置遮罩视图的位置更改
*/
- (void)imageVPanAction:(UIPanGestureRecognizer *)panG{
CGPoint curP = [panG locationInView:self];
if (panG.state == UIGestureRecognizerStateBegan) {
self.beginP = curP;
self.cover.hidden = NO;
}
self.cover.frame = CGRectMake(self.beginP.x, self.beginP.y, curP.x - self.beginP.x, curP.y - self.beginP.y);
if (panG.state == UIGestureRecognizerStateEnded) {
self.toolBar.hidden = NO;
self.toolBar.frame = CGRectMake(self.cover.frame.origin.x, CGRectGetMaxY(self.cover.frame), kToorBarW, kToorBarH);
}
}
/**
* 实现遮罩视图拖拽手势调用方法
* 改变遮罩视图位置,拖拽时.
*/
- (void)coverPanAction:(UIPanGestureRecognizer *)panG{
CGPoint curP = [panG translationInView:self.cover];
self.cover.transform = CGAffineTransformTranslate(self.cover.transform, curP.x, curP.y);
// 复位
[panG setTranslation:CGPointZero inView:self.cover];
}
/**
* 点击了工具类上的裁剪按钮,将遮罩视图范围内的内容裁剪下来.
*/
- (void)clipAction{
if (self.cover.hidden == YES) {
return;
}
self.cover.hidden = YES;
// 裁剪
// 开启位图上下文
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0);
// 设置裁剪区域
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.cover.frame];
[path addClip];
// 绘制图片
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭位图上下文
UIGraphicsEndImageContext();
self.image = image;
}
/**
* 撤销(隐藏遮罩视图和工具条,还原初始图片)
*/
- (void)doAgainClip{
if (self.image != nil) {
self.cover.hidden = YES;
self.toolBar.hidden = YES;
self.image = self.oraginImage;
}
}
/**
* 重写父类方法,记录需要裁剪的图片,以便撤销操作时还原
*/
- (nonnull instancetype)initWithImage:(nullable UIImage *)image{
NSLog(@"%s", __func__);
self.oraginImage = image;
return [super initWithImage:image];
}
@end
- 2.使用
#import "ViewController.h"
#import "ClipImageView.h"
@implementation ViewController
- (BOOL)prefersStatusBarHidden{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
/**
1、添加imageView (代码实现方式)
*/
UIImage *image = [UIImage imageNamed:@"火影"];
ClipImageView *clipImageView = [[ClipImageView alloc] initWithImage:image];
clipImageView.frame = self.view.bounds;
[self.view addSubview:clipImageView];
/**
2、可以在xib中配置,UIImageView的custom class属性为ClipImageView,然后设置Image属性,即可进行裁剪图片了.
*/
}
@end