IOS学习笔记 运用Quartz 2D框架绘图理论基础(1)

理论基础:

Core Graphics(核心图层)框架是一组基于C的API,可以用于一切绘图操作!

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

Quartz2D是一个二维图形绘制引擎,主要用来绘制二维图形,可以实现很多功能如:基于路径的绘图、透明度、阴影、颜色、管理、反锯齿、PDF文档的生成和PDF元数据访问等


Quartz2D与分辨率和设备无关意味着代码不管是在打印机还是其他设备都可以直接运行


在Xcode新建好项目,运用时不必引入Quartz2D框架的头文件这是因为:


项目中已经包含了#import <UIKit/UIKit.h>这个文件,而UIKit依赖于Core Graphics,那么Core Graphics框架会被自动引入,即UIKit内部已经包含了Core Graphics框架的主头文件,为了让开发者不必接触底层的Core Graphics的C接口UIKit内部已经封装了Core Graphics的一些API,但是有时候也可以直接利用Core Graphics的C接口。


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


理论中几个比较重要的概念:


1、图形:以路径的方式描述的一个形状。就是个形状比如圆、长方形等几何图形或者非几何图形只不过这里成为路径

2、图像:简单的说就是很多的像素点逐一绘制在屏幕上所呈现的路径


可以发现:图形和图像很类似,那么做个简单的对比吧


图形:是通过代码绘制路径的方式实现,因此可以是任何图形包括复杂图形。而且在绘制简单图形时效率高于图像。现在主要研究的就是图形的绘制


图像:可借助如PS、Adobe等三方工具,可以预先绘制并以文件形式保存。官方建议PNG格式的图像




绘图思路:


在哪里绘图?给视图中绘图,在图形上下文 Graphics Context  因此新建的项目没有View 

只有控制器和StroyBoard前者是用来控制页面上视图显示的而后者没有绑定任何View呢


那么首先应该是在UIView中,然后在UIView的上下文中就可绘图

因此在ios中如果想在屏幕上绘图,需要创建一个UIView对象,并实现它的drawRect:方法,此方法在UIView显示在屏幕上及UIView内部的内容需要更新时调用,而且一个UIView需要被刷新或者重绘也会被调用(重绘时应该调用setNeedsDisplay而不能直接调用drawRect:方法,因为setNeedsDisplay会自动调用drawRect:方法)


执行方法后UIView对象自动配置绘图环境然后执行绘图操作


在配置的时候UIView对象会对绘图环境创建一个Graphics Context.通过调用UIGraphicsGetCurrentContext()方法获取当前的Graphics Context


Graphics Context是一个数据类型(CGContextRef),封装了Quartz绘图制图到输出设备的信息

Quartz2D中所有的对象都是绘制到一个Graphics Context中,不同的设备有不同的Graphics Context,一个Graphics Context表示一个绘制目标,它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息


如何绘图——-


要绘图首先要理解几个概念:

1、Quartz2D 坐标系 

默认的坐标(0,0)是左下角在ios中,运用UIGraphicsGetCurrentContext方法返回的图形将上下文的坐标原点修改到左上角(即沿着Y值从上到下增大,X值从左到右增大)


有时候需要修改坐标系来达到某些效果,比如屏幕的旋转。因此屏幕的旋转只不过是对上下文中的坐标系的操作而已。


操作坐标系的方法有:

(1)CGContextRotateCTM(CGContextRef c,CGFloat angle) 方法可以相对原点旋转上下文坐标系


(2)CGContextTranslateCTM(CGContextRef c,CGFloat x,CGFloat y) 方法可以相对原点平移上下文坐标系


(3)CGContexScaleCTM(CGContextRef c,CGFloat x,CGFloat y) 方法可以缩放上下文坐标系


注意:

转换坐标系前,使用CGContextSaveGState(CGContextRef c) 保存当前上下文状态

转换坐标系后,使用CGContextRestoreGSate(CGContextRef c) 恢复之前保存的上下文状态


2、绘图顺序


3、UIView的drawRect:方法

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

如果UIView初始化时没有设置CGRectdrawRect:方法不会被调用

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

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


4、Quartz2D 的内存管理

使用含有“Create“或者”Copy“的函数创建的对象,使用完毕后必须释放否则导致内存泄漏,反之则不用释放

如果retain了一个对象,不再使用需要将其release掉。可以使用Quartz2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorSpace对象则使用CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。也可以使用Core Foundation的CFRetain和CFRelease.  一定不能传递NULL值给这些函数



Quartz 2D绘图的基本步骤:


1、获取与视图相关的上下文对象

- UIGraphicsGetCurrentContext


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

(1)创建路径

(2)设置路径起点

(3)增加路径内容

3、将路径添加到上下文

4、设置上下文属性

- 比如:边线颜色、填充颜色、线宽。。。

5、绘制路径

6、释放路径



最基本的绘图:


绘制直线以及其他常见的几何图形


建立项目:


1218绘制简单的几何图形 


新建好项目后,因为没有视图所以新建一个YLMyView.h,然后在StoryBorad中指定一下,那么当程序启动的时候通过加载StoryBoard就可以加载新建的View了。新建的好的View中会自动生成代码:


- (id)initWithFrame:(CGRect)frame

{

   self = [super initWithFrame:frame];

   if (self) {

        // Initialization code

    }

    returnself;

}



但是这个方法将不会被执行,项目中所有的控制器或者View一旦通过StoryBoard或XIB加载后,它们的init方法都不被执行


//

//  YLMyView.m

//  1218绘制简单的几何图形

//

//  Created by apple on 13-12-21.

//  Copyright (c) 2013  All rights reserved.

//


#import "YLMyView.h"


@implementation YLMyView


/*

 下面的代码是使用Quartz 2D框架绘图,而Quartz 2D是一套C语言的框架

 那么先了解下C语言的使用方法:

 1>C语言中所有的对象,都是通过对象的引用地址来使用的,因此不需要使用*

 NSString *str = @"hello word";

 

 在引用的时候会这么写:

 if(str == nil){

 这里的str是指针(习惯用语)实际是内存地址内存地址是用一串

 

 准确的说是无符号的长整型

 

 nil 代表空 准确的说是0

 C语言的角度判断:非0即针

 

 而代码中如:CGContextRef context = UIGraphicsGetCurrentContext();

 是直接通过对象的引用地址来访问的

 

 通过一段代码来表示:

 NSString *str = @"Hello Word";

 CGContextRef context = UIGraphGetCurrentContext();

 这俩行代码执行后,通过断点显示:

 str = _NSCFConstantString *@"Hello Word"

 context = CGContextRef0x8a5ec40

 可以看出:

 context直接打印的是一个十六进制的数那意味着c语言中的对象是直接通过引用对象内存地址来使用的

 str打印的。。。。那么oc中的对象是通过什么来使用的呢?*号代表访问内存。。。指针。。。

 

 

 2>C语言是面向过程的语言,因此要引用某一个对象是通过函数来实现的

 比如:CGContextRef context = UIGraphicsGetCurrentContext();在右边想获取context对象就是通过UIGraphicsGetCurrentContext()方法来实现的

 

 3> ARCOC的自动引用技术,如果是在C语言中,为对象分配了(create,copy)了内存,我们要自己释放对象的内存(释放可以使用Release方法)

 

 CGMutablePathRef path = CGPathCreateMutable();

 右边代码引用的是C语言中的函数,因此必须释放内存。这里涉及到了ARC和非ARC对象释放内存的问题!需要整理笔记!

 

 4> 从代码中可以看出绘图使用了很多Core Graphics(核心图层)里面的类,因此很多都是以CG开头的,比如上下文CGContext-- 路径CGPath--

 

 5> 设置线条颜色

 设置RGB颜色后面四个参数分别是:红绿透明度

 red 美工数值为 0255程序员值为 0FF(将0255转为16进制)比如:#00FF

 green 美工数值为 0255程序员值为 0FF(将0255转为16进制)比如:#00FF

 blue 美工数值为 0255程序员值为 0FF(将0255转为16进制)比如:#00FF

 

 OC中设置RGB颜色:

 red --> r(0~255)/255  值为 01

 green --> g(0~255)/255  值为 01

 blue --> b(0~255)/255  值为 01

 alpha 值为 01.0   0表示完全透明 1表示完全不透明Quartz 2D 绘图的时候默认为1如果改变值的话会严重影响性能

 

 */


/*


 所有的绘制代码在这里调用系统自动生成

 

 */

- (void)drawRect:(CGRect)rect

{

//    NSString *str = @"hello word";

//    CGContextRef context = UIGraphicsGetCurrentContext();

    

    [selfdrawLine];

}



#pragma mark 绘制条直线


- (void)drawLine

{

    // 1获取当前视图中的上下文  执行右边代码将原点修改到左上角(0,0)

  CGContextRef context =UIGraphicsGetCurrentContext();

    

    // 2 设置路径 含有create 使用完毕必须释放

  CGMutablePathRef path =CGPathCreateMutable();

    

    // 2.1 将原点移动到坐标(100,100) NUll表示不使用形变 

   CGPathMoveToPoint(path,NULL,100, 100);

    

    

    // 2.2 增加一条直线  可以理解是将坐标(100,100)的点移动到坐标(200,200)

    CGPathAddLineToPoint(path,NULL,200,200);

    

    // 3 将路径添加到上下文

    CGContextAddPath(context, path);

    

    // 4设置上下文的属性设置线条颜色为红色

    

    CGContextSetRGBStrokeColor(context,1.0,0,0,1);

    

    /* 5将上下文中的路径绘制出来  即将点移动的轨迹绘制出来

     

     // 方法中的第二个参数是填充模式定义了很多种填充方式(值以K开头)

     

enum CGPathDrawingMode {

     kCGPathFill,               // 填充绘制针对关闭的路径使用 中间重合部分也填充

     kCGPathEOFill,             // 抑或填充针对关闭的路径使用 中间重合部分不填充

     kCGPathStroke,             // 绘制线条无所谓路径是否关闭

     kCGPathFillStroke,         // 填充并绘制线条

     kCGPathEOFillStroke        // 抑或填充并画线

     };

    */

  CGContextDrawPath(context,kCGPathStroke);

  

    

    

    // 6释放路径这句代码涉及到内存管理:在C语言中含有creat或者copy函数所创建的对象,是哟哦那个完毕后必须释放否则内存泄漏

  CGPathRelease(path);

    

}


@end






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值