裁剪截屏.gif
- 核心代碼:
如果要將裁剪后的上下文渲染到控件上,必須設置要將其到控件的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