iOS Quart2D绘图

UIGraphicsBeginImageContextWithOptions函数一定要有对应的UIGraphicsEndImageContext函数作为结尾,不然会有内存泄漏

/*
 * 参数一: 指定将来创建出来的bitmap的大小
 * 参数二: 设置透明YES代表透明,NO代表不透明
 * 参数三: 代表缩放,0代表不缩放
 */
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);

绘制图片

  1. 开启一个图形上下文
  2. 绘制图片
  3. 从当前上下文获取新的图片
  4. 关闭上下文
    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;
}

给图片添加图片水印

iOS Quart2D绘图_第1张图片
添加图片.png
  1. 开启一个图形上下文
  2. 绘制图片
  3. 把水印图片绘制到当前上下文
  4. 从当前上下文获取新的图片
  5. 关闭上下文
    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;
}

给图片添加文字

iOS Quart2D绘图_第2张图片
添加文字.png
  1. 开启一个图形上下文
  2. 绘制图片
  3. 把文字绘制到当前上下文
  4. 从当前上下文获取新的图片
  5. 关闭上下文
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;
}

裁剪圆形图片

iOS Quart2D绘图_第3张图片
裁剪.png
  1. 开启一个图形上下文
  2. 设置裁剪区域
  3. 把图片绘制到当前上下文
  4. 从当前上下文获取新的图片
  5. 关闭上下文
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;
}

裁剪带边框的圆形图片
iOS Quart2D绘图_第4张图片
边框.png

    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;
}

截屏

  1. 开启一个图形上下文
  2. 获取当前上下文
  3. 截屏,渲染到当前上下文中,这里使用绘制无效,可自行测试
  4. 从当前上下文获取新的图片
  5. 把图片转化成为NSData类型
  6. 关闭上下文
  7. 把新的图片和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;
}

正方形空心遮罩

iOS Quart2D绘图_第5张图片
kCAFillRuleEvenOdd
- (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基础

你可能感兴趣的:(iOS Quart2D绘图)