美文网首页
iOS--Quartz2D(上)

iOS--Quartz2D(上)

作者: 空白Null | 来源:发表于2016-07-07 16:02 被阅读131次

    一、Quartz2D基本概念

    1、Quartz2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境

    2、Quartz2D API可以实现很多功能,如基于路径的绘图、透明度、阴影、颜色管理、反锯齿、PDF文档生成和PDF元数据访问等

    3、Quartz2D API是Core Graphics框架的一部分,因此其中的很多数据类型和方法都是以CG开头的

    4、Quartz2D与分辨率和设备无关,因此在使用Quartz2D绘图时,无需考虑最终绘图的目标设备

    二、Core Graphics    

    1、该框架是一组基于C的API,可以用于一切绘图操作,这个框架的重要性,仅次于UIKit和Foundation    

    2、当使用UIKit创建按钮、标签或者其他UIView的子类时,UIKit会用Core Graphics将这些元素绘制在屏幕上,此外,UIEvent也会使用Core Graphics,用来帮组确定触摸时间在屏幕上所处的位置    

    3、因为UIKit依赖于Core Graphics,所以当引入时,Core Graphics框架会被自动引入

    4、为了让开发者不必触及底层的Core Graphics的C接口,UIKit内部封装了Core Graphics的一些API,可以快速生成通用的界面元素,但是,有时候直接利用Core Graphics的C接口是很有必要和很有好处的,比如创建一个自定义的界面元素

    三、Quartz2D的几个重要概念

    1、图像上下文(Graphics Context) - 相当于一个画笔

    1) Graphics Context是一个数据类型(CGContextRef),封装了Quartz绘制图像到输出设备的信息,输出设备可以是PDF文件、Bitmap(位图文件,一种图形文件)或者显示器的窗口上

    2)Quartz中所有的对象都是绘制到一个Graphics Context中

    3)当用Quartz绘图时,所有设备相关的特性都包含在Graphics Context中,换句话说,我们可以简单地给Quartz绘图序列指定不同的Graphics Context,就可将相同的图像绘制在不同的设备上,而不需要任何设备相关的计算,这些都有Quartz替我们完成

    2、Quartz2D坐标系

    1)Quartz中默认的坐标系统是:原定(0,0)在左下角,沿着X轴从左到右坐标值逐渐增大,沿着Y轴从下到上左键增加

    2)有些技术在设置他们的graphics Context时使用了不同于Quartz的默认坐标系统,最常见的是系统原点修改为左上角

    3)坐标系的转换

    //相对原点旋转上下文坐标系

    CGContextRotateCTM(CGContextRef c, CGFloat angle)

    //相对原点平移上下文坐标系

    CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

    //缩放上下文坐标系

    CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)

    PS:

    注意:

    转换坐标系前,使用方法保存当前上下文状态

    CGContextSaveGState(CGContextRef c)

    坐标系转换后,使用方法恢复之前保存的上下文状态

    CGContextRestoreGState(CGContextRef c)可以

    3、Quartz2D的绘图顺序

    1)谁后绘制谁显示在顶部,即叠加到最上面

    2)利用Quartz2D绘制UIView

    当在UIView子类中重写drawRect方法时,iOS会自动准备好一个图像上下文,可以通过调用UIGraphicsGetCurrentContext()来获取

    3)只要一个UIView需要被刷新或者重绘,drawRect方法就会被调用,需要注意的是:重绘时应该调用setneedsDisplay,而不能直接调用drawRect,setNeedsDisplay会自动调用drawRect:

    4) drawRect注意事项

    drawRect:是在UIViewController的loadView和viewDidLoad两方法之后调用的

    drawRect:如果试图没有设置frame,将导致该方法不能执行

    如果设置UIView的contentMode属性值为UIViewContentModeRedraw,那么将在每次更改frame时自动调用drawRect:

    如果使用UIView绘图,只能在drawRect:方法中获取相应的CGContextRef并绘图,而在其他方法中获取的CGContextRef不能用于绘图

    4、Quartz内存管理

    1)使用含有"Create"或"Copy"的函数创建的对象,使用完后必须释放,否则将导致内存泄露,使用不含有"Create"或"Copy"的函数获取的对象,则不需要释放

    2)如果retain了一个对象,不再使用时需要将其release掉,可以使用Quratz2D的函数来指定retain和release一个对象,例如创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象,也可以使用CoreFoundation的CFRetain和CGRelease。注意不能传递NULL值给这些函数

    5、Quartz2D绘图的基础元素-路径

    路径定义了一条或者多条形状或子路径

    子路径可以包含一条或者多条直线或曲线

    子路径也可以是一些简单的形状,例如线、圆形、矩形或者星型等

    子路径还可以包含复杂的形状,例如地图轮廓或者涂鸦等

    路径是可以是开放的,也可以是封闭的,对于封闭路径可以是空心的也可以是实心的

    四、练习,都是在drawRect方法内操作

    1、基本绘图,使用Path实现

    1)获取与试图相关联的上下文对象

    //提示:使用Ref声明的对象,不需要用*

    CGContextRef context = UIGraphicsGetCurrentContext();

    2)创建及设置路径(path)

    创建路径

    CGMutablePathRef path = CGPathCreateMutable();

    设置路径起点

    CGPathMoveToPoint(path, NULL, 50, 50);

    增加路径内容

    CGPathAddLineToPoint(path, NULL, 200,200);

    CGPathAddLineToPoint(path, NULL, 50, 200);

    封闭路径

    CGPathAddLineToPoint(path, NULL, 50, 50);

    CGPathCloseSubpath(path);

    上面这两个函数都可以用来封闭路径,但后者在设置顶点样式时会使样式无效

    3) 将路径添加到上下文

    CGContextAddPath(context, path);

    4)设置上下文状态

    边线颜色

    CGContextSetRGBStrokeColor(context, 0.7, 0.7, 0.5, 1);

    填充颜色

    CGContextSetRGBFillColor(context, 1, 0, 0, 1);

    线宽

    CGContextSetLineWidth(context, 10);

    设置线条的顶点样式

    CGContextSetLineCap(context, kCGLineCapButt);

    设置线条的连接点样式

    CGContextSetLineJoin(context, kCGLineJoinRound);

    设置线条的虚线样式

    context

    phase 相位,虚线起始的位置,通常使用0即可,从头开始画虚线

    lengths 长度的数组

    count lengths数组的个数

    CGFloat lengths[4] = {40.0, 40.0};

    CGContextSetLineDash(context, 0.0, lengths, 2);

    5)绘制路径

    kCGPathStroke: 画线(空心)

    kCGPathFill:  填充(实心)

    kCGPathFillStroke: 即画线又填充

    CGContextDrawPath(context, kCGPathFillStroke);

    6)释放路径

    CGPathRelease(path);

    2、基本绘图,上下文的默认路径实现

    1)获取上下文

    CGContextRef context = UIGraphicsGetCurrentContext();

    2)设置当前上下文的路径

    设置路径起点

    CGContextMoveToPoint(context, 50, 50);

    增加路径内容

    CGContextAddLineToPoint(context, 200, 200);

    CGContextAddLineToPoint(context, 50, 200);

    封闭路径

    CGContextClosePath(context);

    CGContextAddLineToPoint(context, 50, 50);

    3) 设置上下文状态

    CGContextSetLineWidth(context, 10); //线条宽

    CGContextSetLineJoin(context, kCGLineJoinRound); //连接点样式

    CGContextSetLineCap(context, kCGLineCapRound);  //顶点样式

    4)绘制路径,虽然没有直接定义路径,但是第二步操作,就是为上下文指定路径

    CGContextDrawPath(context, kCGPathFillStroke);

    3、绘制矩形

    CGRect rect = CGRectMake(50, 50, 200, 200);

    [[UIColor redColor] setStroke];

    [[UIColor grayColor] setFill];

    //绘制实心矩形

    UIRectFill(rect);

    //绘制空心矩形

    UIRectFrame(rect);

    4、绘制圆形

    1. 取出上下文

    CGContextRef context = UIGraphicsGetCurrentContext();

    2. 设置路径

    CGRect rect = CGRectMake(50, 50, 200, 200);

    Ellipse圆形

    CGContextAddEllipseInRect(context, rect);

    3. 绘制路径

    CGContextDrawPath(context, kCGPathFillStroke);

    5、绘制弧度

    CGContextRef context = UIGraphicsGetCurrentContext();

    context 上下文

    x,y 是圆弧所在圆的中心点坐标

    radius 半径,所在圆的半径

    startAngle endAngle 起始角度和截止角度 单位是弧度 M_PI =3.14

    0度 对应是圆的最右侧点

    clockwise 顺时针 0 或者逆时针 1

    CGContextAddArc(context, 100, 100, 100, 0, M_PI_2, 1);

    [[UIColor grayColor] setFill];

    CGContextDrawPath(context, kCGPathFill);

    6、绘制图像

    UIImage *image = [UIImage imageNamed:@"头像1.png"];

    //提示:绘制之后,就无法改变位置,也没有办法监听手势识别

    在指定点绘制图像

    //[image drawAtPoint:CGPointMake(50, 50)];

    //会在指定的矩形中拉伸绘制

    [image drawInRect:CGRectMake(0, 0, 320, 460)];

    //在指定矩形区域中平铺图片

    [image drawAsPatternInRect:CGRectMake(0, 0, 320, 460)];

    7、绘制文字

    NSString *string = @"时间到了反馈结束了的开发就流口水的减肥来看就";

    //在指定点绘制文字

    [string drawAtPoint:CGPointMake(0, 0) withAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

    //在指定的矩形区域绘制文字

    CGRect rect = CGRectMake(50, 50, 210, 360);

    [string drawInRect:rect withAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

    提示:如果不在drawRect方法中调用绘图方法,上下文地址都是0,不能直接进行绘制

    8、绘制水印图片

    1. 建立图像的上下文,需要指定新生成的图像大小

    CGSize imageSize = CGSizeMake(320, 200);

    UIGraphicsBeginImageContext(imageSize);

    2、绘制图片

    UIImage *image = [UIImage imageNamed:@"NatGeo01.png"];

    [image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];

    3、绘制矩形

    [[UIColor yellowColor]set];

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextAddRect(context, CGRectMake(50, 50, 100, 100));

    CGContextDrawPath(context, kCGPathEOFill);

    4、添加水印文字

    NSString *str = @"我的水印";

    [str drawInRect:CGRectMake(0, imageSize.height - 30, imageSize.width - 20, 30)  withAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

    5、获取到新生成的图像,从当前上下文获取到新绘制的图像

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    6、关闭图像上下文

    UIGraphicsEndImageContext();

    相关文章

      网友评论

          本文标题:iOS--Quartz2D(上)

          本文链接:https://www.haomeiwen.com/subject/qcsljttx.html