Quartz2D

一、绘图的几种方式

1.最原始的绘图方式

    // 1.获取图形上下文
    // 目前我们所用的上下文都是以UIGraphics
    // CGContextRef Ref:引用 CG:目前使用到的类型和函数 一般都是CG开头 CoreGraphics
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 2.描述路径
    // 创建路径
    CGMutablePathRef path = CGPathCreateMutable();
    
    // 设置起点
    // path:给哪个路径设置起点
    CGPathMoveToPoint(path, NULL, 50, 50);
    
    // 添加一根线到某个点
    CGPathAddLineToPoint(path, NULL, 200, 200);
    
    // 3.把路径添加到上下文
    CGContextAddPath(ctx, path);
    
    // 4.渲染上下文
    CGContextStrokePath(ctx);

2.绘图的第二种方式

   // 获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 描述路径
    // 设置起点
    CGContextMoveToPoint(ctx, 50, 50);
    
    CGContextAddLineToPoint(ctx, 200, 200);
    // 设置绘图状态,一定要在渲染之前
    // 颜色
    [[UIColor redColor] setStroke];
    
    // 线宽
    CGContextSetLineWidth(ctx, 5);
    
    // 设置连接样式
    CGContextSetLineJoin(ctx, kCGLineJoinBevel);
    
    // 设置顶角样式
    CGContextSetLineCap(ctx, kCGLineCapRound);
    // 渲染上下文
    CGContextStrokePath(ctx);

3.绘图的第三种方式

   // UIKit已经封装了一些绘图的功能
    
    // 贝瑟尔路径
    // 创建路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    // 设置起点
    [path moveToPoint:CGPointMake(50, 50)];
    
    // 添加一根线到某个点
    [path addLineToPoint:CGPointMake(200, 200)];
    [[UIColor greenColor] set];
    
    path.lineWidth = 3;
    // 绘制路径
    [path stroke];

二、花圆弧

 // 圆弧
    // Center:圆心
    // startAngle:弧度
    // clockwise:YES:顺时针 NO:逆时针
    
    // 扇形
    CGPoint center = CGPointMake(125, 125);
     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
    
    // 添加一根线到圆心
    [path addLineToPoint:center];
    
    
   [path stroke];
    
   // 填充:必须是一个完整的封闭路径,默认就会自动关闭路径
   //    [path fill];

三、画矩形

 UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];
 [[self colorRandom] set];
 [path fill];

- (UIColor *)colorRandom
{
    // 0 ~ 255 / 255
    // OC:0 ~ 1
    CGFloat r = arc4random_uniform(256) / 255.0;
    CGFloat g = arc4random_uniform(256) / 255.0;
    CGFloat b = arc4random_uniform(256) / 255.0;
    return [UIColor colorWithRed:r green:g blue:b alpha:1];
    
}

四、绘制文字和图片

1.绘制普通文字

// 绘制文字
    
    NSString *str = @"asfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdfasfdsfsdf";
    // 不会换行
    //    [str drawAtPoint:CGPointZero withAttributes:nil];
    
    [str drawInRect:self.bounds withAttributes:nil];

2.绘制富文本文字

// 绘制文字
    
    NSString *str = @"asfdsfsdf";
    
    
    // 文字的起点
    // Attributes:文本属性

    NSMutableDictionary *textDict = [NSMutableDictionary dictionary];

    // 设置文字颜色
    textDict[NSForegroundColorAttributeName] = [UIColor redColor];

    // 设置文字字体
    textDict[NSFontAttributeName] = [UIFont systemFontOfSize:30];

    // 设置文字的空心颜色和宽度

    textDict[NSStrokeWidthAttributeName] = @3;

    textDict[NSStrokeColorAttributeName] = [UIColor yellowColor];

    // 创建阴影对象
    NSShadow *shadow = [[NSShadow alloc] init];
    shadow.shadowColor = [UIColor greenColor];
    shadow.shadowOffset = CGSizeMake(4, 4);
    shadow.shadowBlurRadius = 3;
    textDict[NSShadowAttributeName] = shadow;

    // 富文本:给普通的文字添加颜色,字体大小
    [str drawAtPoint:CGPointZero withAttributes:textDict];

3.绘制图片

// 超出裁剪区域的内容全部裁剪掉
    // 注意:裁剪必须放在绘制之前
    UIRectClip(CGRectMake(0, 0, 50, 50));
    
    UIImage *image = [UIImage imageNamed:@"001"];
    
    // 默认绘制的内容尺寸跟图片尺寸一样大
//    [image drawAtPoint:CGPointZero];
    
//    [image drawInRect:rect];
    // 绘图
    [image drawAsPatternInRect:rect];

五、图形上下文状态栈

// 如果以后用贝瑟尔绘制图形【path stroke】,上下文的状态由贝瑟尔路径状态
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    
    // 1.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 2.描述路径
    // 第一根
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(10, 125)];
    
    [path addLineToPoint:CGPointMake(240, 125)];
    
    // 把路径添加到上下文
    // .CGPath 可以UIkit的路径转换成CoreGraphics路径
    CGContextAddPath(ctx, path.CGPath);
    
    // 保存一份上下文的状态
    CGContextSaveGState(ctx);
    
    
    
    // 设置上下文状态
    CGContextSetLineWidth(ctx, 10);
    
    [[UIColor redColor] set];
   
    // 渲染上下文
    CGContextStrokePath(ctx);
    
    // 第二根
    
   
    
    // 2.描述路径
    // 第一根
    path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(125, 10)];
    
    [path addLineToPoint:CGPointMake(125, 240)];
    
    // 把路径添加到上下文
    // .CGPath 可以UIkit的路径转换成CoreGraphics路径
    CGContextAddPath(ctx, path.CGPath);
    
    // 还原状态
    CGContextRestoreGState(ctx);
//    // 设置上下文状态
//    CGContextSetLineWidth(ctx, 1);
//    
//    [[UIColor blackColor] set];
    
    // 渲染上下文
    CGContextStrokePath(ctx);
    
}

六、矩阵操作

- (void)drawRect:(CGRect)rect {
    
    // 1.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    
    // 2.描述路径
   UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-100, -50, 200, 100)];
    
    [[UIColor redColor] set];
    
    // 上下文矩阵操作
    // 注意:矩阵操作必须要在添加路径之前
    
    //  平移
    CGContextTranslateCTM(ctx, 100, 50);
    
    // 缩放
    CGContextScaleCTM(ctx, 0.5, 0.5);
    
    // 旋转
    
    CGContextRotateCTM(ctx, M_PI_4);
    
    // 3.把路径添加上下文
    CGContextAddPath(ctx, path.CGPath);

    
    
    [[UIColor redColor] set];
    
    
    // 4.渲染上下文
    CGContextFillPath(ctx);
    
    
    
    
}

七、位图上下文

1.图片水印

    // 加载图片
    UIImage *image = [UIImage imageNamed:@"小黄人"];
    
    // 0.获取上下文,之前的上下文都是在view的drawRect方法中获取(跟View相关联的上下文layer上下文)
    // 目前我们需要绘制图片到新的图片上,因此需要用到位图上下文
    
    // 怎么获取位图上下文,注意位图上下文的获取方式跟layer上下文不一样。位图上下文需要我们手动创建。
    
    // 开启一个位图上下文,注意位图上下文跟view无关联,所以不需要在drawRect.
    // size:位图上下文的尺寸(新图片的尺寸)
    // opaque: 不透明度 YES:不透明 NO:透明,通常我们一般都弄透明的上下文
    // scale:通常不需要缩放上下文,取值为0,表示不缩放
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    
    
//    // 1.获取上下文(位图上下文)
//    CGContextRef ctx = UIGraphicsGetCurrentContext();
//    
//    // 2.描述路径
//    CGContextMoveToPoint(ctx, 50, 50);
//    
//    CGContextAddLineToPoint(ctx, 200, 200);
//    
//    [[UIColor redColor] set];
//    
//    // 3.渲染上下文
//    CGContextStrokePath(ctx);
    
    
    UIBezierPath *path =[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];
    
    [[UIColor redColor] set];
    [path stroke];
    
    
//    // 1.绘制原生的图片
//    [image drawAtPoint:CGPointZero];
//    
//    // 2.给原生的图片添加文字
//    NSString *str = @"小码哥";
//    
//    // 创建字典属性
//    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
//    dict[NSForegroundColorAttributeName] = [UIColor redColor];
//    dict[NSFontAttributeName] = [UIFont systemFontOfSize:20];
//    
//    [str drawAtPoint:CGPointMake(200, 528) withAttributes:dict];
    
    // 3.生成一张图片给我们,从上下文中获取图片
    UIImage *imageWater = UIGraphicsGetImageFromCurrentImageContext();
    
    // 4.关闭上下文
    UIGraphicsEndImageContext();
    
    _imageView.image = imageWater;
    
    

2.图片裁剪

// 0.加载图片
    UIImage *image = [UIImage imageNamed:@"阿狸头像"];
    
    // 1.开启位图上下文,跟图片尺寸一样大
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    
    // 2.设置圆形裁剪区域,正切与图片
    // 2.1创建圆形的路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    
    // 2.2把路径设置为裁剪区域
    [path addClip];
    
    // 3.绘制图片
    [image drawAtPoint:CGPointZero];
    
    // 4.从上下文中获取图片
    UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();
    
    // 5.关闭上下文
    UIGraphicsEndImageContext();
    
    _imageView.image = clipImage;

3.屏幕截屏

+ (UIImage *)imageWithCaputureView:(UIView *)view
{
    // 开启位图上下文
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
    
    // 获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 把控件上的图层渲染到上下文,layer只能渲染
    [view.layer renderInContext:ctx];
    
    // 生成一张图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
    // 关闭上下文
    UIGraphicsEndImageContext();
    
    return image;
}
UIImage *image =  [UIImage imageWithCaputureView:self.view];
    
    // image转data
    // compressionQuality: 图片质量 1:最高质量
    
  NSData *data = UIImageJPEGRepresentation(image,1);
    
  [data writeToFile:@"/Users/xiaomage/Desktop/view.png" atomically:YES];

4.图片截取

- (UIView *)clipView{
    if (_clipView == nil) {
        UIView *view = [[UIView alloc] init];
        _clipView = view;
        
        view.backgroundColor = [UIColor blackColor];
        view.alpha = 0.5;
        
        [self.view addSubview:view];
    }
    
    return _clipView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 给控制器的view添加一个pan手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    
    [self.view addGestureRecognizer:pan];
}

- (void)pan:(UIPanGestureRecognizer *)pan
{
    CGPoint endA = CGPointZero;
    
    if (pan.state == UIGestureRecognizerStateBegan) { // 一开始拖动的时候
        
        // 获取一开始触摸点
      _startP = [pan locationInView:self.view];
        
    }else if(pan.state == UIGestureRecognizerStateChanged){ // 一直拖动
        // 获取结束点
         endA = [pan locationInView:self.view];
        
        CGFloat w = endA.x - _startP.x;
        CGFloat h = endA.y - _startP.y;
        
        // 获取截取范围
        CGRect clipRect = CGRectMake(_startP.x, _startP.y, w, h);

        
        // 生成截屏的view
        self.clipView.frame = clipRect;
        
        
        
    }else if (pan.state == UIGestureRecognizerStateEnded){
        
        
        // 图片裁剪,生成一张新的图片
        
        // 开启上下文
        // 如果不透明,默认超出裁剪区域会变成黑色,通常都是透明
        UIGraphicsBeginImageContextWithOptions(_imageV.bounds.size, NO, 0);
        
        // 设置裁剪区域
       UIBezierPath *path =  [UIBezierPath bezierPathWithRect:_clipView.frame];
        
        [path addClip];
        
        // 获取上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 把控件上的内容渲染到上下文
        [_imageV.layer renderInContext:ctx];
        
        
        // 生成一张新的图片
        _imageV.image = UIGraphicsGetImageFromCurrentImageContext();
        
        
        // 关闭上下文
        UIGraphicsEndImageContext();
        
        
        // 先移除
        [_clipView removeFromSuperview];
        // 截取的view设置为nil
        _clipView = nil;
        
    }
    

5.屏幕擦除

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    
    [self.view addGestureRecognizer:pan];
}


- (void)pan:(UIPanGestureRecognizer *)pan
{
    // 获取当前点
    CGPoint curP = [pan locationInView:self.view];
    
    // 获取擦除的矩形范围
    CGFloat wh = 100;
    CGFloat x = curP.x - wh * 0.5;
    CGFloat y = curP.y - wh * 0.5;
    
    CGRect rect = CGRectMake(x, y, wh, wh);
    
    // 开启上下文
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 控件的layer渲染上去
    [_imageView.layer renderInContext:ctx];
    
    // 擦除图片
    CGContextClearRect(ctx, rect);
    
    // 生成一张图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
    _imageView.image = image;
    
    // 关闭上下文
    UIGraphicsEndImageContext();
    
    
}

你可能感兴趣的:(Quartz2D)