UIGraphicsBeginImageContextWithOptions函数一定要有对应的UIGraphicsEndImageContext函数作为结尾,不然会有内存泄漏
/*
* 参数一: 指定将来创建出来的bitmap的大小
* 参数二: 设置透明YES代表透明,NO代表不透明
* 参数三: 代表缩放,0代表不缩放
*/
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);
绘制图片
- 开启一个图形上下文
- 绘制图片
- 从当前上下文获取新的图片
- 关闭上下文
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
imageView.image = [UIImage pq_drawImageWithImageNamed:@"222.png"];
[self.view addSubview:imageView];
+ (UIImage *)pq_drawImageWithImageNamed:(NSString *)name{
//1.获取图片
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]];
//2.开启图形上下文
UIGraphicsBeginImageContext(image.size);
//3.绘制到图形上下文中
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//4.从上下文中获取图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.关闭图形上下文
UIGraphicsEndImageContext();
//返回图片
return newImage;
}
给图片添加图片水印
- 开启一个图形上下文
- 绘制图片
- 把水印图片绘制到当前上下文
- 从当前上下文获取新的图片
- 关闭上下文
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
imageView.image = [UIImage pq_WaterImageWithImage:[UIImage imageNamed:@"222"] waterImage:[UIImage imageNamed:@"222"] waterImageRect:CGRectMake(30, 30, 50, 50)];
[self.view addSubview:imageView];
+ (UIImage *)pq_WaterImageWithImage:(UIImage *)image waterImage:(UIImage *)waterImage waterImageRect:(CGRect)rect{
//1.开启上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.绘制背景图片
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//绘制水印图片到当前上下文
[waterImage drawInRect:rect];
//3.从上下文中获取新图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//4.关闭图形上下文
UIGraphicsEndImageContext();
//返回图片
return newImage;
}
给图片添加文字
- 开启一个图形上下文
- 绘制图片
- 把文字绘制到当前上下文
- 从当前上下文获取新的图片
- 关闭上下文
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
//设置字体样式
NSMutableDictionary * dict = [NSMutableDictionary dictionary];
//NSFontAttributeName:字体大小
dict[NSFontAttributeName] = [UIFont systemFontOfSize:25];
//字体前景色
dict[NSForegroundColorAttributeName] = [UIColor blueColor];
//字体背景色
dict[NSBackgroundColorAttributeName] = [UIColor redColor];
//字体阴影
NSShadow * shadow = [[NSShadow alloc]init];
//阴影偏移量
shadow.shadowOffset = CGSizeMake(3, 5);
//阴影颜色
shadow.shadowColor = [UIColor greenColor];
//高斯模糊
shadow.shadowBlurRadius = 5;
dict[NSShadowAttributeName] = shadow;
//字体间距
dict[NSKernAttributeName] = @10;
imageView.image = [UIImage pq_WaterImageWithImage:[UIImage imageNamed:@"222"] text:@"纸巾艺术" textPoint:CGPointMake(30, 30) attributedString:dict];
[self.view addSubview:imageView];
+ (UIImage *)pq_WaterImageWithImage:(UIImage *)image text:(NSString *)text textPoint:(CGPoint)point attributedString:(NSDictionary * )attributed{
//1.开启上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.绘制图片
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//添加水印文字
[text drawAtPoint:point withAttributes:attributed];
//3.从上下文中获取新图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//4.关闭图形上下文
UIGraphicsEndImageContext();
//返回图片
return newImage;
}
裁剪圆形图片
- 开启一个图形上下文
- 设置裁剪区域
- 把图片绘制到当前上下文
- 从当前上下文获取新的图片
- 关闭上下文
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
UIImage * image = [UIImage imageNamed:@"222"];
imageView.image = [UIImage pq_ClipCircleImageWithImage:image circleRect:CGRectMake(0, 0, image.size.width, image.size.height)];
[self.view addSubview:imageView];
+ (nullable UIImage *)pq_ClipCircleImageWithImage:(nullable UIImage *)image circleRect:(CGRect)rect{
//1、开启上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2、设置裁剪区域
UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:rect];
[path addClip];
//3、绘制图片
[image drawAtPoint:CGPointZero];
//4、获取新图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5、关闭上下文
UIGraphicsEndImageContext();
//6、返回新图片
return newImage;
}
裁剪带边框的圆形图片
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
UIImage * image = [UIImage imageNamed:@"222"];
imageView.image = [UIImage pq_ClipCircleImageWithImage:image circleRect:CGRectMake(0, 0, image.size.width, image.size.height) borderWidth:10 borderColor:[UIColor greenColor]];
[self.view addSubview:imageView];
+ (nullable UIImage *)pq_ClipCircleImageWithImage:(nullable UIImage *)image circleRect:(CGRect)rect borderWidth:(CGFloat)borderW borderColor:(nullable UIColor *)borderColor{
//1、开启上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2、设置边框
UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:rect];
[borderColor setFill];
[path fill];
//3、设置裁剪区域
UIBezierPath * clipPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(rect.origin.x + borderW , rect.origin.x + borderW , rect.size.width - borderW * 2, rect.size.height - borderW *2)];
[clipPath addClip];
//3、绘制图片
[image drawAtPoint:CGPointZero];
//4、获取新图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5、关闭上下文
UIGraphicsEndImageContext();
//6、返回新图片
return newImage;
}
截屏
- 开启一个图形上下文
- 获取当前上下文
- 截屏,渲染到当前上下文中,这里使用绘制无效,可自行测试
- 从当前上下文获取新的图片
- 把图片转化成为NSData类型
- 关闭上下文
- 把新的图片和NSData类型直接放回,便于显示和保存截屏
[UIImage pq_cutScreenWithView:self.view successBlock:^(UIImage * _Nullable image, NSData * _Nullable imagedata) {
if (image) {
NSLog(@"截取成功");
NSString * path = [NSString stringWithFormat:@"%@/Documents/cut.jpg",NSHomeDirectory()];
if( [imagedata writeToFile:path atomically:YES]){
NSLog(@"保存成功%@",path);
}
}
}];
+ (void)pq_cutScreenWithView:(nullable UIView *)view successBlock:(nullable void(^)(UIImage * _Nullable image,NSData * _Nullable imagedata))block{
//1、开启上下文
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
//2.获取当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//3.截屏
[view.layer renderInContext:ctx];
//4、获取新图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.转化成为Data
//compressionQuality:表示压缩比 0 - 1的取值范围
NSData * data = UIImageJPEGRepresentation(newImage, 1);
//6、关闭上下文
UIGraphicsEndImageContext();
//7.回调
block(newImage,data);
}
擦除
- (UIImageView *)wipeImageV{
if (!_wipeImageV) {
UIImageView * imageView = [[UIImageView alloc]initWithFrame:self.view.bounds];
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"fore.jpg" ofType:nil]];
imageView.image = image;
[self.view addSubview:imageView];
_wipeImageV = imageView;
}
return _wipeImageV;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
UIImageView * imageView = [[UIImageView alloc]initWithFrame:self.view.bounds];
imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"back.jpg" ofType:nil]];
[self.view addSubview:imageView];
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(wipePanGestureEvent:)];
self.wipeImageV.userInteractionEnabled = YES;
[self.wipeImageV addGestureRecognizer:pan];
}
- (void)wipePanGestureEvent:(UIPanGestureRecognizer * )pan{
//封装后如下
self.wipeImageV.image = [self.wipeImageV.image pq_wipeImageWithView:self.wipeImageV currentPoint:[pan locationInView:self.wipeImageV] size:CGSizeMake(40, 40)];
}
- (nullable UIImage *)pq_wipeImageWithView:(nullable UIView *)view currentPoint:(CGPoint)nowPoint size:(CGSize)size{
//计算位置
CGFloat offsetX = nowPoint.x - size.width * 0.5;
CGFloat offsetY = nowPoint.y - size.height * 0.5;
CGRect clipRect = CGRectMake(offsetX, offsetY, size.width, size.height);
//开启上下文
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
//获取当前的上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//把图片绘制上去
[view.layer renderInContext:ctx];
//把这一块设置为透明
CGContextClearRect(ctx, clipRect);
//获取新的图片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
//重新赋值图片
return newImage;
}
正方形空心遮罩
- (void)setQuadrateWithCenter:(CGPoint)center width:(CGFloat)width {
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
//设置需要抠掉的正放形路径
UIBezierPath *quadratePath = [UIBezierPath bezierPathWithRect:CGRectMake(center.x - width * 0.5, center.y - width * 0.5, width, width)];
[path appendPath:quadratePath];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = path.CGPath;
shapeLayer.fillRule = kCAFillRuleEvenOdd;
[self.layer setMask:shapeLayer];
}
kCAFillRuleEvenOdd,绘制两个Rect的非交集
iOS Quart2D绘图之UIGraphicsBeginImageContextWithOptions基础