今天看了一下Quartz 2D绘图,我只想说:不要把绘图和动画那些东西当做一个很复杂的东西,其实只要你认真看还是可以理解的。他们并不难。啰嗦了几句,现在直接进入正题:

前提是我们必须新建一个singleviewApplication。具体新建就不多说了,然后我们自己写一个UIView的子类,然后创建子类加载到故事板中。(你也可以直接把故事板中的ViewControler的view的父类定义为你自己创建的类),然后我们的操作都是在drawRectangular:方法中实现的:(我采用的是直接修改View的父类为我自定义的类)

下面的就是代码:我们一个一个来跟着代码理解:

1、首先是最简单的填充颜色:

- (void)drawRect:(CGRect)rect {
// setFill设置填充的颜色
[[UIColor redColor] setFill]; //随后需要填充的颜色设置
UIRectFill(rect); //用当前的颜色进行填充
}

其中:

setFill方法:它的作用就是设置随后填充操作用到的颜色。

UIRectFill():该方法就是用刚才设置的颜色进行填充。

结果如下:

我们没有在ViewController中的修改任何属性,这只是在自定义的View中完成的。

2、使用UIRectFrame画一个矩形:

- (void)drawRect:(CGRect)rect {
//setStroke设置描边的颜色
[[UIColor redColor] setStroke];
CGRect frame = CGRectMake(, , , );
UIRectFrame(frame);
}

其中:

setStroke:是设置随后描边用到的颜色

UIRectFrame():根据指定的rect画一个框架。

结果如下:

3、然后是NSString类的绘制文本方法:

- (void)drawRect:(CGRect)rect {
NSString *s = [NSString stringWithFormat:@"zhangsan"];
//这里面drawAtPoint就是绘制文本的方法
[s drawAtPoint:CGPointMake(, ) withAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:]}];
}

运行效果如下:

其中主要用的的方法就是drawAtPoint:那个方法

另外还有drawInRect方法。具体的方法介绍就不做过多介绍了。

4、画三角形

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext(); //创建图形上下文
  CGContextSaveGState(context); //保存当前图形上下文设置
CGContextMoveToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextClosePath(context);
[[UIColor redColor] setFill];
[[UIColor blackColor] setStroke];
CGContextDrawPath(context, kCGPathFillStroke);
  CGContextRestoreGState(context); //恢复图形上下文设置
}

效果如下:

其中遇到了新的东西:CGContextRef。不要害怕遇到CG,其实很简单。

首先,一句

 CGContextRef context = UIGraphicsGetCurrentContext();  //创建图形上下文

创建了上下文,什么是上下文?????你可以直接把他理解成一个Quartz 2D的绘画环境。

就是对每个的绘画操作都需要一个绘画环境,然后才能进行绘画操作。而UIGraphicsGetCurrentContext()就是获取当前的绘画环境,

然后里面有:

CGContextMoveToPoint:就是绘画的起始点。

CGContextAddLineToPoint:就是从刚才绘画起始点到你在这个函数中指定的点。

最后用CGContextClosePath去封闭这三个点组成的图形。这样一个三角形就出来。

NO,NO,还需要CGContextDrawPath来进行操作哦。它的作用是绘制当前路径用提供的绘制模型:这里用的kCGPathFillStroke,就是描边填充模型,其他的模型读者可以自己查看。

忘了,忘了。还有两个方法没介绍:

CGContextSaveGState(context):它的作用是为当前的上下文保存一个复制。官方介绍是压一份复制的当前绘画状态到绘画状态栈中。也就是压栈操作。

CGContextRestoreGState(context):设置当前绘画状态 为最近保存的一份状态。可以理解为出栈操作。

使用这两个函数的原因:有事后需要多次改变图形上下文对象的参数,这样两次绘制就可能相互影响,这就好像拿着蜡笔画画,每一次只能拿一个。为了防止相互影响所以要保存上下文设置,绘制完成后我们在用restore那个函数回复图形上下文。

5、Quartz路径

Core Graphics中有4种基本图元用于描述路径:点、线、弧和贝塞尔(Bezier)曲线。前两种都不用介绍了都见过,后面的贝塞尔曲线和弧需要说一下。

弧:可以由圆心点、半径、起始角和结束角描述。圆是弧的一个特例。只需要这只起始角度为0,结束角度为360就可以了。

贝塞尔曲线:任何一条曲线都可以通过与他相切的控制线两端的点的位置定义。具体我也不太理解,先没看就。如果你理解的深刻可以给我说一下。

6、坐标变换

首先要理解:在Quartz 2D中的坐标系和UIKit坐标系是相反的。什么意思勒?就是

Quartz 2D坐标系原点在左下角,x向右为正方向,y向上为正方向

UIKit坐标系原点在左上角,x向右为正方向,y向下为正方向。

现在就让我们继续看看坐标变换把。

--------------------------------为了书写方便下面的方法我直接提取出来了,只需要在drawRect:方法里面调用就行了--------------------------------

7、画一张图片:

//反向image
- (void)drawImage {
/*
图形的另一种操作就是变换:包括评议、缩放和旋转等形式的变换
Quartz 2D坐标系和UIKit坐标系是相反的。
*/
CGContextRef context = UIGraphicsGetCurrentContext();
UIImage *image = [UIImage imageNamed:@"test"];
CGImageRef cgImage = image.CGImage;
CGRect rect = CGRectMake(, , image.size.width, image.size.height);
CGContextDrawImage(context, rect, cgImage);
//由于坐标系相反,所以图形是返回来的。
}

运行一下看看:

这图片怎么长这样,我开始也纳闷,后来知道了,原来它是倒着放的。因为什么呢?因为Quartz 2D坐标系和UIKit的相反,所以会造成这种情况。

先不管反正了。反正画了一个图片到view上。看看代码。应该不用过多介绍了。CGContextDrawImage和刚才的CGContextDrawPath类似,只不过画的东西不一样罢了。里面要说下CGImageRef:它是一个结构体:封装了位图图像的信息。而UIImaged的CGImage就是返回的这样的实例。其他不说了。

8、2D图形基本变换:

有平移变换、缩放变换、旋转变换、x轴对称变换、y轴对称变换、坐标原点对称变换。具体的都不详细介绍了。应该都能理解那些变换的意思。

9、CTM变换矩阵

不要看着CTM几个字母就害怕,其实它就是current transformation matrix的简称。就是当前矩阵变换。Quartz 2D提供了多种形式的变换,其中主要是CTM和仿射(Affine)变换。看一下CTM吧。

CTM主要涉及的函数有:

CGContextRotateCTM:旋转变换

CGContextScaleCTM:缩放变换

CGContextTranslateCTM:平移变换

举个简单栗子:

- (void)tanslateImage {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
UIImage *image = [UIImage imageNamed:@"test"];
CGImageRef cgImage = image.CGImage;
// CGContextTranslateCTM(context, 0, image.size.height);
// CGContextScaleCTM(context, -1, 1); CGContextTranslateCTM(context, , ); //移动它的位置到100,50
// CGContextRotateCTM(context, 360);
CGRect rect = CGRectMake(, , image.size.width, image.size.height);
CGContextDrawImage(context, rect, cgImage);
CGContextRestoreGState(context);
}

看看结果:

使用了CGContextTranslateCTM,我们可以进行位置调整。这里我把位置向右向下移动了50.就成这样了。哪些旋转和缩小就不说了,自己尝试一把。

这里给出来代码,可以试试:

/**旋转变换*/

#define radians(x) (x*M_PI/180)

- (void)rotateImage {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
UIImage *image = [UIImage imageNamed:@"test"];
CGImageRef cgImage = image.CGImage;
CGContextRotateCTM(context, radians(-.));
CGRect rect = CGRectMake(, , image.size.width, image.size.height);
CGContextDrawImage(context, rect, cgImage);
CGContextRestoreGState(context);
}
/**缩小变换*/
- (void)scaleImage {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
UIImage *image = [UIImage imageNamed:@"test"];
CGImageRef cgImage = image.CGImage;
CGContextScaleCTM(context, ., .); //设置缩小大小
CGRect rect = CGRectMake(, image.size.height, image.size.width, image.size.height);
CGContextDrawImage(context, rect, cgImage);
}

最后再给出一个比较厉害的让你的图片旋转过来的方法:

//正向image
- (void)drawNormalImage {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context); //保留初始上下文
UIImage *image = [UIImage imageNamed:@"test"];
CGImageRef cgImage = image.CGImage; CGContextTranslateCTM(context, , image.size.height); //先做平移变换
CGContextScaleCTM(context, , -); //缩放变换x不变,y相反
CGRect rect = CGRectMake(, , image.size.width, image.size.height);
CGContextDrawImage(context, rect, cgImage);
CGContextRestoreGState(context); //还原初始上下文
// CGContextScaleCTM(context, -1, 1);
// CGContextDrawImage(context, rect, cgImage); }

其实让图片正过来很简单,先做了平移变换,然后又缩放了一把,就0k了。

------------------------------------------------看累了吗?继续看。马上完--------------------------------

仿射变换(Affine)

也是一种2D变换,他可以重用变换,经过多次变换,每一种变换都可以用矩阵表示,通过多次矩阵相乘得到最后结果。(矩阵太难了。。。。。。。。。没关系,理解就行了)

下面是一些访射变换函数:

CGAffineMakeRotation:创建新的旋转变换矩阵

CGAffineMakeScale:创建新的 缩放矩阵函数

CGAffineMakeTranslation:创建新的平移矩阵

CGAffineTransformRotate:旋转矩阵

CGAffineTransformScale:缩放矩阵

CGAffineTransformTranslate:平移矩阵

CGContextConcatCTM:连接到CTM变换。

这么多函数。这么多函数。这么多函数。太难了。。。。。。不过没事。看看下面的例子你应该就可以理解了。

- (void)normalImageByAffine {
UIImage *image = [UIImage imageNamed:@"test"];
CGImageRef cgImage = image.CGImage;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGAffineTransform myAffine = CGAffineTransformMakeTranslation(, image.size.height); myAffine = CGAffineTransformScale(myAffine, , -);
CGContextConcatCTM(context, myAffine);
CGRect rect = CGRectMake(, , image.size.width, image.size.height);
CGContextDrawImage(context, rect, cgImage);
CGContextRestoreGState(context);
}

这个方法是通过仿射变换把刚刚倒过来的图形放正。可以看一下:

CGAFffineTransform就是一个结构体,可以用来接收CGAffineTransformMakeTranslate创建的仿射(平移)矩阵。

然后又CGAffineTransformScale:通过里面的参数来设置缩放矩阵.然后用CGContextConcatCTM连接到CTM变换。这样就实现了图像的正过来。drawNormalImage方法实现的效果是一样的。

----------------------------------------------------这里是结束----------------------------------------------------

没有了,这里就是结束了。

给个代码把?好的好的。下面就是源码:写的比较乱,能看懂就行了。

http://pan.baidu.com/s/1kTMUyX5

谢谢百度网盘给的空间。

Quartz 2d绘图的更多相关文章

  1. iOS基础 - Quartz 2D绘图的基本步骤

    一.使用Quartz 2D绘图的基本步骤 1) 获取上下文context(绘制图形的地方) 2) 设置路径(路径是用来描述形状的) 3)  将路径添加到上下文 4)  设置上下文属性(设置颜色,线宽, ...

  2. iOS基础 - Quartz 2D绘图

    一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...

  3. Core Graphics框架 利用Quartz 2D绘图

    首先,什么是Core Graphics和Quartz 2D? Core Graphics:是基于Quartz 2D绘图引擎的一个C语言的API绘图框架.它也是iOS开发中最基本的框架(Framewor ...

  4. 关于Quartz 2D绘图的简单使用

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ...

  5. 1.1 Quartz 2D 绘图

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书”   Quartz2D 绘图主要步骤:   1. 获取[图形上下文]对象 —— (拿到草稿纸 ...

  6. iOS - Quartz 2D 二维绘图

    1.Quartz 2D 简介 Quartz 2D 属于 Core Graphics(所以大多数相关方法的都是以 CG 开头),是 iOS/Mac OSX 提供的在内核之上的强大的 2D 绘图引擎,并且 ...

  7. iOS - Quartz 2D 贝塞尔曲线

    1.贝塞尔曲线 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支 ...

  8. iOS_Quartz 2D绘图

    目  录: 一.基础知识掌握 二.Quartz 2D绘图基础:CGContextRef实现简单地绘制图形 三.CGContextRef实现文字.图片.基于路径的图形绘制 四.在内存中绘制位图 五.添加 ...

  9. Quartz 2D(常用API函数、绘制图形、点线模式)

    Quzrtz 2D 绘图的核心 API 是 CGContextRef ,它专门用于绘制各种图形. 绘制图形关键是两步: 1.获取 CGContextRef ; 2.调用 CGContextRef 的方 ...

随机推荐

  1. 利用SVN工具下载OpenCore代码

    OpenCore原来使用的是CVS管理代码的.从09年起,更换用SVN管理代码,大家可以用TortoiseSVN软件下载代码,网址是:http://tortoisesvn.net/,安装后tortoi ...

  2. 编写高质量JS代码的68个有效方法(五)

    No.21.使用apply方法通过不同数量的参数调用函数 Tips: 使用apply方法自定一个可计算的参数数组来调用可变参数的函数 使用apply方法的第一个参数给可变参数的方法提供一个接收者 // ...

  3. Java 随机数

    本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示. 广义上讲,Java中的随机数的有三种产生方式:(01). 通过System.currentTimeMillis()来获取一个当前时间 ...

  4. [转载]SharePoint 2013搜索爬外网配置

    本文介绍SharePoint 2013 设置外网(Internet)爬网源: 下面是步聚: 1. 新建外部爬网源 a. 打开 “SharePoint 2013 Central Administrati ...

  5. 测试lua的效率

    这几天粗略的测试了一下lua的效率!首先声明这个测试很有针对性,大部分是针对游戏中的使用,而绝非lua的整体性效率(这个测试我不会),lua构建的上层逻辑中,大概使用的语句不太多,for,迭代,调用C ...

  6. 在做excel导出时如何将excel直接写在输出流中

    之前做excel导出时,我都是先将文件写在服务器上,然后再下载下来,后来发现原来可以直接将文件写在输出流里边. 下面是一个小demo: package com.huaqin.fcstrp.util; ...

  7. EF容器---代理类对象

    #region 修改--官方的修改是,先查询,然后修改 /// <summary> /// 修改--官方的修改是,先查询,然后修改 /// </summary> static ...

  8. Apache log4net™ 手册——概述【翻译】

    原文地址 本文内容 概述 框架 日志(Loggers)和追加器(Appenders) 日志层次(Logger hierarchy) 追加器(Appenders) 筛选(Filters) 布局(Layo ...

  9. 克隆复制可使用原型( Prototype)设计模式

    今天有学习设计模式的原型(Prototype)<设计模式--原型(Prototype)模式>http://www.cnblogs.com/insus/p/4152773.html .为了加 ...

  10. 实用笔记-EF中直接运行SQL命令

    在EF4.1,API的名字 有了些许改变,DbContext.Database就是对应于数据库端信息的封装.执行SQL命令也自然从Database类型开始.对应于ExecuteStoreCommand ...