Quartz2D

转载自:http://blog.csdn.net/maomaopanjiu/article/details/46900463


Quartz2D

标签(空格分隔): ios进阶

什么是Quartz2D

  • Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统,Quartz 2D能生成绘制图形、绘制文字、绘制\生成图像、读取\生成PDF、截图\裁剪图片
    自定义UI控件 ……
  • 有些UI界面极其复杂、而且比较个性化,用普通的UI控件无法实现,这时可以利用Quartz2D技术将控件内部的结构画出来,自定义控件的样子,iOS中大部分控件的内容都是通过Quartz2D画出来的,Quartz2D在iOS开发中很重要的一个价值是:自定义view(自定义UI控件)

图形上下文

图形上下文的作用
- 保存绘图信息、绘图状态
- 决定绘制的输出目标(绘制到什么地方去?)

  • Quartz2D提供了以下几种类型的Graphics Context:

    • Bitmap Graphics Context
    • PDF Graphics Context
    • Window Graphics Context
    • Layer Graphics Context
    • Printer Graphics Context

自定义view

自定义view步骤

  • 新建一个类,继承自UIView
  • 实现 - (void)drawRect:(CGRect)rect 方法
    • (在 drawRect: 方法中才能取得跟view相关联的图形上下文)
    • 系统在调用drawRect方法,会自动帮你创建一根跟view相关联的上下文,并且传递给你
    • 调用view的 setNeedsDisplay 或者 setNeedsDisplayInRect: 时系统会调用该方法
  • - (void)drawRect:(CGRect)rect 方法中取得跟当前view相关联的图形上下文
  • 绘制相应的图形内容
  • 利用图形上下文将绘制的所有内容渲染显示到view上面
    - (void)drawRect:(CGRect)rect {
 // 1.获取上下文
 CGContextRef ctx = UIGraphicsGetCurrentContext();
 // 2.拼接路径
 UIBezierPath *path = [UIBezierPath bezierPath];
 [path moveToPoint:CGPointMake(10, 125)];
 [path addQuadCurveToPoint:CGPointMake(240, 125) controlPoint:CGPointMake(125, 0)];
 //设置属性
 path.lineWidth = 20;
 [[UIColor redColor]set];
 // 3.路径添加到上下文
 CGContextAddPath(ctx, path.CGPath);
 // 4.渲染上下文
//CGContextFillPath(ctx);
CGContextStrokePath(ctx);

##常用拼接路径函数

- 新建一个起点

void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)
- 添加新的线段到某个点

void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)

- 添加一个矩形

void CGContextAddRect(CGContextRef c, CGRect rect)

- 添加一个椭圆

void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)

- 添加一个圆弧
void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,
CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)

##常用绘制路径函数

- Mode参数决定绘制的模式

void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
- 绘制空心路径

void CGContextStrokePath(CGContextRef c)

- 绘制实心路径

void CGContextFillPath(CGContextRef c)

矩阵操作

  • 注意点:必须要在添加路径之前进行形变
  • 利用矩阵操作,能让绘制到上下文中的所有路径一起发生变化

    • 缩放

      void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
    • 旋转

      void CGContextRotateCTM(CGContextRef c, CGFloat angle)
    • 平移

      void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

图形上下文栈

  • 将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”)

    void CGContextSaveGState(CGContextRef c)
  • 将栈顶的上下文出栈,替换掉当前的上下文

    void CGContextRestoreGState(CGContextRef c)

图片水印

  • 由于需要最后得到一张图片而不是在屏幕上显示,所以用 Bitmap Graphics Context 图片上下文,这样就不能在 - (void)drawRect:(CGRect)rect 方法中获取上下文,需要自己开启,使用结束后也需要自己结束
  • 核心代码

    • 开启一个基于位图的图形上下文

      void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
    • 从上下文中取得图片(UIImage)

      UIImage* UIGraphicsGetImageFromCurrentImageContext();
    • 结束基于位图的图形上下文

      void UIGraphicsEndImageContext();

代码示例

UIImage *image = [UIImage imageNamed:@"图片"];
// 创建位图上下文
// size:上下文尺寸
// opaque:不透明 Yes 不透明 透明 NO
// scale:是否缩放上下文,0表示不要缩放
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);

[image drawAtPoint:CGPointZero];
// 文字
NSString *str = @"文字";
//文字属性
 // 描述文字的属性,颜色,字体大小
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
// 字体
attr[NSFontAttributeName] = [UIFont systemFontOfSize:50];
// 颜色
attr[NSForegroundColorAttributeName] = [UIColor redColor];
// 边框颜色
attr[NSStrokeColorAttributeName] = [UIColor redColor];
// 边框宽度
attr[NSStrokeWidthAttributeName] = @1;
//文字阴影
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowOffset = CGSizeMake(3, 3);
shadow.shadowColor = [UIColor yellowColor];
shadow.shadowBlurRadius = 3;
attr[NSShadowAttributeName] = shadow;

[str drawAtPoint:CGPointMake(0, 0) withAttributes:nil];

// 根据上下文的内容生成一张图片
image = UIGraphicsGetImageFromCurrentImageContext();

// 关闭上下文
UIGraphicsEndImageContext();

// 用来网络中传输图片
NSData *data = UIImagePNGRepresentation(image);

[data writeToFile:@"/Users/apple/Desktop/image.png" atomically:YES];

图片裁剪

void CGContextClip(CGContextRef c) - 将当前上下所绘制的路径裁剪出来(超出这个裁剪区域的都不能显示)

知识点补充

CADisplayLink

  • 使用代码
//每次屏幕刷新的时候就会触发,通常我们的屏幕一秒刷新60次,
//注意:调用setNeedsDisplay并不会马上触发drawRect方法,仅仅是给当前这个view设置一个重新绘制的标志,等下一次屏幕刷新的时候才会去调用drawRect
  CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值