第三十四篇:Quartz2D绘图
2015-10-27 19:30
260 查看
Quartz2D在iOS开发中的价值
•自定义view(自定义UI控件)
2.图形上下文
1)图形上下文(Graphics Context):是一个CGContextRef类型的数据
2)图形上下文的作用
Ø保存绘图信息、绘图状态
Ø决定绘制的输出目标(绘制到什么地方去?)
(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)
相同的一套绘图序列,指定不同的GraphicsContext,就可将相同的图像绘制到不同的目标上
4)Quartz2D提供了以下几种类型的Graphics Context:
ØBitmapGraphics Context
ØPDFGraphicsContext
ØWindowGraphicsContext
ØLayerGraphicsContext
ØPrinterGraphicsContext
自定义view
1)如何利用Quartz2D绘制东西到view上?
Ø首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去
Ø其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面
2)自定义view的步骤
Ø新建一个类,继承自UIView
Ø实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中
>取得跟当前view相关联的图形上下文
>绘制相应的图形内容
>利用图形上下文将绘制的所有内容渲染显示到view上面
3)
》为什么要实现drawRect:方法才能绘图到view上?
Ø因为在drawRect:方法中才能取得跟view相关联的图形上下文
》drawRect:方法在什么时候被调用?
Ø当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
Ø调用view的setNeedsDisplay或者setNeedsDisplayInRect:时
4)drawRect:中取得的上下文
》在drawRect:方法中取得上下文后,就可以绘制东西到view上
》View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了
》View之所以能显示东西,完全是因为它内部的layer
4.Quartz2D绘图的代码步骤
1)获得图形上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
2)拼接路径(下面代码是搞一条线段)
CGContextMoveToPoint(ctx,10,10);
CGContextAddLineToPoint(ctx,100,100);
3)绘制路径
CGContextStrokePath(ctx);//CGContextFillPath(ctx);
5.绘图的一些方法
链接一:https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/index.html#//apple_ref/c/func/CGContextAddArc
链接二:http://donbe.blog.163.com/blog/static/138048021201052093633776/
示例链接:http://blog.csdn.net/JianglongHuang/article/details/44871133
重绘(刷帧,即自动重调用UIView的对象方法:- (void)drawRect:(CGRect)rect
)
UIView对象方法
获得图形上下文:
用图形上下文栈,存储当前图形上下方及其复原
图形上下文的 旋转,缩放,平移
指定一个点成为current point,Quartz会跟踪current point一般执行完一个相关函数后,current point都会相应的改变.
创建一条直线,从current point到 (x,y),然后current point会变成(x,y)
创建多条直线,比如points有两个点,那么会画两条直线 从current point到 (x1,y1), 然后是(x1,y1)到(x2,y2),然后current
point会变成points中的最后一个点
形成封闭图形
设置线宽状态:
设置线两端的形状
设置填充的颜色
裁剪图形
画一个椭圆
[objc] view
plaincopyprint?
CGContextAddEllipseInRect(CGContextRef _Nullable c, CGRect rect)
出一个距形
[objc] view
plaincopyprint?
CGContextAddRect(CGContextRef _Nullable c, CGRect rect)
CGContextAddRects(CGContextRef _Nullable c, const CGRect * _Nullable rects, size_t count)
弧:Arcs
两种方法创建弧度 第一种
[objc] view
plaincopyprint?
void CGContextAddArc (
CGContextRef c,
CGFloat x, //圆心的x坐标
CGFloat y, //圆心的x坐标
CGFloat radius, //圆的半径
CGFloat startAngle, //开始弧度
CGFloat endAngle, //结束弧度
int clockwise //0表示顺时针,1表示逆时针
);
假如想创建一个完整的圆圈,那么 开始弧度就是0 结束弧度是 2pi, 因为圆周长是 2*pi*r.
最后,函数执行完后,current point就被重置为(x,y).
还有一点要注意的是,假如当前path已经存在一个subpath,那么这个函数执行的另外一个效果是
会有一条直线,从current point到弧的起点
第二种
[objc] view
plaincopyprint?
void CGContextAddArcToPoint (
CGContextRef c,
CGFloat x1, //端点1的x坐标
CGFloat y1, //端点1的y坐标
CGFloat x2, //端点2的x坐标
CGFloat y2, //端点2的y坐标
CGFloat radius //半径
);
原理:首先画两条线,这两条线分别是 current point to (x1,y1) 和(x1,y1) to (x2,y2).
这样就是出现一个以(x1,y1)为顶点的两条射线,
然后定义半径长度,这个半径是垂直于两条射线的,这样就能决定一个圆了,更好的理解看下图,不过个人认为下图所标的 tangent point 1的位置是错误的。
最后,函数执行完后,current point就被重置为(x2,y2).
还有一点要注意的是,假如当前path已经存在一个subpath,那么这个函数执行的另外一个效果是
会有一条直线,从current point到(x1,y1)
画曲线
画文字
NSString 对象方法:
[objc] view
plaincopyprint?
- (void)drawInRect:(CGRect) withAttributes:(nullable NSDictionary<NSString *,id> *);
- (void)drawAtPoint:(CGPoint) withAttributes:(nullable NSDictionary<NSString *,id> *);
画图片
UIImage 对象方法:
[objc] view
plaincopyprint?
- (void)drawAsPatternInRect:(CGRect);
- (void)drawInRect:(CGRect);
- (void)drawAtPoint:(CGPoint);
.......
常用绘制路径函数
[objc] view
plaincopyprint?
//Mode参数决定绘制的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
//绘制空心路径
void CGContextStrokePath(CGContextRef c)
//绘制实心路径
void CGContextFillPath(CGContextRef c)
图片水印
//开启一个基于位图的图形上下文
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
//从上下文中取得图片(UIImage)
UIImage* UIGraphicsGetImageFromCurrentImageContext();
//结束基于位图的图形上下文
void UIGraphicsEndImageContext();
屏幕截图
//调用某个view的layer的renderInContext:方法即可
- (void)renderInContext:(CGContextRef)ctx;
•自定义view(自定义UI控件)
2.图形上下文
1)图形上下文(Graphics Context):是一个CGContextRef类型的数据
2)图形上下文的作用
Ø保存绘图信息、绘图状态
Ø决定绘制的输出目标(绘制到什么地方去?)
(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)
相同的一套绘图序列,指定不同的GraphicsContext,就可将相同的图像绘制到不同的目标上
4)Quartz2D提供了以下几种类型的Graphics Context:
ØBitmapGraphics Context
ØPDFGraphicsContext
ØWindowGraphicsContext
ØLayerGraphicsContext
ØPrinterGraphicsContext
自定义view
1)如何利用Quartz2D绘制东西到view上?
Ø首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去
Ø其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面
2)自定义view的步骤
Ø新建一个类,继承自UIView
Ø实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中
>取得跟当前view相关联的图形上下文
>绘制相应的图形内容
>利用图形上下文将绘制的所有内容渲染显示到view上面
3)
》为什么要实现drawRect:方法才能绘图到view上?
Ø因为在drawRect:方法中才能取得跟view相关联的图形上下文
》drawRect:方法在什么时候被调用?
Ø当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
Ø调用view的setNeedsDisplay或者setNeedsDisplayInRect:时
4)drawRect:中取得的上下文
》在drawRect:方法中取得上下文后,就可以绘制东西到view上
》View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了
》View之所以能显示东西,完全是因为它内部的layer
4.Quartz2D绘图的代码步骤
1)获得图形上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
2)拼接路径(下面代码是搞一条线段)
CGContextMoveToPoint(ctx,10,10);
CGContextAddLineToPoint(ctx,100,100);
3)绘制路径
CGContextStrokePath(ctx);//CGContextFillPath(ctx);
5.绘图的一些方法
链接一:https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/index.html#//apple_ref/c/func/CGContextAddArc
链接二:http://donbe.blog.163.com/blog/static/138048021201052093633776/
示例链接:http://blog.csdn.net/JianglongHuang/article/details/44871133
重绘(刷帧,即自动重调用UIView的对象方法:- (void)drawRect:(CGRect)rect
)
UIView对象方法
// 图形上下文全部内容重绘 - (void)setNeedsDisplay; // 图形上下文柜形框内的内容重绘 - (void)setNeedsDisplayInRect:(CGRect);
获得图形上下文:
UIGraphicsGetCurrentContext()
用图形上下文栈,存储当前图形上下方及其复原
CGContextSaveGState(CGContextRef _Nullable c) CGContextRestoreGState(CGContextRef _Nullable c)
图形上下文的 旋转,缩放,平移
// 图形上下文中的内容旋转了angle角度 CGContextRotateCTM(CGContextRef _Nullable c, CGFloat angle) // 图形上下文中的内容缩放比例 CGContextScaleCTM(CGContextRef _Nullable c, CGFloat sx, CGFloat sy) // 图形上下文中的内容x,y的平移 CGContextTranslateCTM(CGContextRef _Nullable c, CGFloat tx, CGFloat ty)
指定一个点成为current point,Quartz会跟踪current point一般执行完一个相关函数后,current point都会相应的改变.
void CGContextMoveToPoint (CGContextRef c, CGFloat x,CGFloat y );
创建一条直线,从current point到 (x,y),然后current point会变成(x,y)
void CGContextAddLineToPoint ( CGContextRef c, CGFloat x, CGFloat y );
创建多条直线,比如points有两个点,那么会画两条直线 从current point到 (x1,y1), 然后是(x1,y1)到(x2,y2),然后current
point会变成points中的最后一个点
void CGContextAddLines ( CGContextRef c, const CGPoint points[], size_t count );
形成封闭图形
CGContextClosePath(CGContextRef _Nullable c)
设置线宽状态:
CGContextSetLineWidth(CGContextRef _Nullable c, CGFloat width);
设置线两端的形状
CGContextSetLineCap(CGContextRef _Nullable c, CGLineCap cap)
设置填充的颜色
CGContextSetRGBFillColor(CGContextRef _Nullable c, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) CGContextSetRGBStrokeColor(CGContextRef _Nullable c, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)
裁剪图形
CGContextClip(CGContextRef _Nullable c) CGContextClipToMask(CGContextRef _Nullable c, CGRect rect, CGImageRef _Nullable mask) CGContextClipToRect(CGContextRef _Nullable c, CGRect rect) CGContextClipToRects(CGContextRef _Nullable c, const CGRect * _Nonnull rects, size_t count)
画一个椭圆
[objc] view
plaincopyprint?
CGContextAddEllipseInRect(CGContextRef _Nullable c, CGRect rect)
出一个距形
[objc] view
plaincopyprint?
CGContextAddRect(CGContextRef _Nullable c, CGRect rect)
CGContextAddRects(CGContextRef _Nullable c, const CGRect * _Nullable rects, size_t count)
弧:Arcs
两种方法创建弧度 第一种
[objc] view
plaincopyprint?
void CGContextAddArc (
CGContextRef c,
CGFloat x, //圆心的x坐标
CGFloat y, //圆心的x坐标
CGFloat radius, //圆的半径
CGFloat startAngle, //开始弧度
CGFloat endAngle, //结束弧度
int clockwise //0表示顺时针,1表示逆时针
);
假如想创建一个完整的圆圈,那么 开始弧度就是0 结束弧度是 2pi, 因为圆周长是 2*pi*r.
最后,函数执行完后,current point就被重置为(x,y).
还有一点要注意的是,假如当前path已经存在一个subpath,那么这个函数执行的另外一个效果是
会有一条直线,从current point到弧的起点
第二种
[objc] view
plaincopyprint?
void CGContextAddArcToPoint (
CGContextRef c,
CGFloat x1, //端点1的x坐标
CGFloat y1, //端点1的y坐标
CGFloat x2, //端点2的x坐标
CGFloat y2, //端点2的y坐标
CGFloat radius //半径
);
原理:首先画两条线,这两条线分别是 current point to (x1,y1) 和(x1,y1) to (x2,y2).
这样就是出现一个以(x1,y1)为顶点的两条射线,
然后定义半径长度,这个半径是垂直于两条射线的,这样就能决定一个圆了,更好的理解看下图,不过个人认为下图所标的 tangent point 1的位置是错误的。
最后,函数执行完后,current point就被重置为(x2,y2).
还有一点要注意的是,假如当前path已经存在一个subpath,那么这个函数执行的另外一个效果是
会有一条直线,从current point到(x1,y1)
画曲线
<pre name="code" class="objc">// 一个控制点的曲线 CGContextAddQuadCurveToPoint( CGContextRef _Nullable c, CGFloat cpx, // 控制点x的位置 CGFloat cpy, // 控制点y的位置 CGFloat x, // 直线的终点x的位置 CGFloat y // 直线的终点y的位置 ) // 两个控制点的曲线 CGContextAddCurveToPoint(CGContextRef _Nullable c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y)
画文字
NSString 对象方法:
[objc] view
plaincopyprint?
- (void)drawInRect:(CGRect) withAttributes:(nullable NSDictionary<NSString *,id> *);
- (void)drawAtPoint:(CGPoint) withAttributes:(nullable NSDictionary<NSString *,id> *);
画图片
UIImage 对象方法:
[objc] view
plaincopyprint?
- (void)drawAsPatternInRect:(CGRect);
- (void)drawInRect:(CGRect);
- (void)drawAtPoint:(CGPoint);
.......
常用绘制路径函数
[objc] view
plaincopyprint?
//Mode参数决定绘制的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
//绘制空心路径
void CGContextStrokePath(CGContextRef c)
//绘制实心路径
void CGContextFillPath(CGContextRef c)
图片水印
//开启一个基于位图的图形上下文
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
//从上下文中取得图片(UIImage)
UIImage* UIGraphicsGetImageFromCurrentImageContext();
//结束基于位图的图形上下文
void UIGraphicsEndImageContext();
屏幕截图
//调用某个view的layer的renderInContext:方法即可
- (void)renderInContext:(CGContextRef)ctx;
相关文章推荐
- netstat查看网络信息
- httpclient4.3设置代理请求
- BugPhobia开发篇章:绩效管理的层次优化
- 电子设计自动化实验 实验三 频率计制作
- iOS 统计打点那些事
- Codevs_P2144 砝码称重 2
- Android 读书笔记---Intent 和 IntentFilter
- 小波变换系数的含义
- 第一章Python 初步介绍
- KMP(未测试)
- android数据存储之数据库
- PAT 1015. Reversible Primes (20)
- jQuery学习之旅 Item7 区别this和$(this)
- [转载] Docker网络原则入门:EXPOSE,-p,-P,-link
- python_getopt解析命令行输入参数的使用
- Eclipse黑色背景保护眼睛设置分享
- 您的微通道的二维代码是唯一的权?【秘密微通道的二维码】
- 用命令直接在两台ubuntu之间传输数据
- jQuery学习之旅 Item7 区别this和$(this)
- 两个ListView 嵌套数据出现错位,混淆的,图片闪烁问题