这两天看了关于绘图相关的东西,大致总结一下。只要写下 此刻对绘图的理解,方便以后回忆。
1.绘图方式
底层的就是core graphic ,高层的封装是uikit封装的。
可以在自定义的view 中,drawrect中对视图进行重绘。也可以不自定义,在view controller中处理相关的(比如 截屏,存储)
2.原理
2.1 举例:画一条线
首先需要一个画布(context),如果画一条线,我们需要选择一个合适的画笔:(
CGContextSetLineWidth
),蘸取某个颜色(
[[UIColor blueColor] setStroke]
),然后从一个点(
CGPathMoveToPoint
)移动到另一个点(
CGPathAddLineToPoint
)。然后绘制在画布上。搞定!
完成代码:
CGContextRef
c =
UIGraphicsGetCurrentContext
(
);
CGContextSetLineWidth(c , 20);
[[UIColor brownColor]
setStroke
];
CGContextMoveToPoint(c , 0, 0);CGContextAddLineToPoint(c, self.bounds.size.width/2, self.bounds.size.height/2);
CGContextStrokePath(c);
注:
CGContextSetLineJoin(c , kCGLineJoinBevel); 可以设置两条线段连接处,是圆角,平角还是尖角。
2.2 绘图缓存
直接往画布上绘制没有问题,但是影响效率,所以可以选择,先绘制到缓冲区内,绘制完成后,将内容绘制到画布上。例如上文的绘制线段可以这么做
代码:
CGContextRef
context
=
UIGraphicsGetCurrentContext
(
);
CGMutablePathRef path = CGPathCreateMutable
();//创建
CGPathMoveToPoint (path, NULL , 0 , 0 );
CGPathAddLineToPoint (path, NULL , self . frame . size . width , self . frame . size . height );
CGPathMoveToPoint (path, NULL , self . frame . size . width , 0 );
CGPathAddLineToPoint(path, NULL, 0, self.frame.size.height );
CGContextAddPath (content, path);//将没有颜色等属性的图传入画布中
[[ UIColor blueColor ] setStroke ];//描边
CGContextSetLineWidth ( context , 20 );//画笔宽度
CGPathMoveToPoint (path, NULL , 0 , 0 );
CGPathAddLineToPoint (path, NULL , self . frame . size . width , self . frame . size . height );
CGPathMoveToPoint (path, NULL , self . frame . size . width , 0 );
CGPathAddLineToPoint(path, NULL, 0, self.frame.size.height );
CGContextAddPath (content, path);//将没有颜色等属性的图传入画布中
[[ UIColor blueColor ] setStroke ];//描边
CGContextSetLineWidth ( context , 20 );//画笔宽度
CGContextDrawPath(context , kCGPathStroke);//选取用那种颜色填充,见备注
CGPathRelease
(path);//释放
注:
1. CGContextDrawPath(context , kCGPathStroke);第二个参数说明,如何绘制路径。
enum
CGPathDrawingMode {
kCGPathFill,//只填充
kCGPathEOFill,
kCGPathStroke,//只描边
kCGPathFillStroke,//既描边又填充
kCGPathFill,//只填充
kCGPathEOFill,
kCGPathStroke,//只描边
kCGPathFillStroke,//既描边又填充
kCGPathEOFillStroke
};
};
例如:
[[UIColor redColor] setStroke];
[[UIColor blueColor] setFill];
CGContextDrawPath(content, kCGPathFillStroke);
CGContextDrawPath(content, kCGPathFillStroke);
2. 由于是c语言的core graphics 库,所以记得手动释放内存,
CGPathRelease
(path);
2. 如果对绘制的图进行转换:平移 旋转 还是 缩放。
我们使用
CGAffineTransform...
苹果的文档说的很清楚:xcdoc://?url=developer.apple.com/library/etc/redirect/xcode/ios/889e4b/documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html 或者 去苹果开发文档中搜索
CGAffineTransform。
简单总结就是:通过一个三维矩阵没来决定(x,y.z)。
需哟注意的是:如果我们想转换图片,例如旋转,你有两种方法,一种是将画布旋转,然后绘制在画布上得图自然跟着旋转(
CGContextRotateCTM(CGContextRef c, CGFloat angle)
);一种是画布不懂,图绘制的时候,旋转好绘制到画布上。(
CGAffineTransform t = CGAffineTransformMakeRotation(30/180.0*M_PI);
CGPathAddLineToPoint(path, &t, 0, self.frame.size.height
);
;//可以使用其他的函数,常见的函数有,绘制路径,矩形等
)
注意:当要使用两个转换时候,比如旋转(对应数组A)+放大(对应数组B)我们需要记住最终的变化是A*B 而不是A+B。
所以我们使用是A*B
CGAffineTransform tScale = CGAffineTransformScale(transform, 2, 2);
CGAffineTransform tRotation =CGAffineTransformMakeRotation(
30
/
180.0
*
M_PI
);
CGAffineTransform t = CGAffineTransformConcat(tScale,tRotation);
而不应该是A+B
CGAffineTransform tScale = CGAffineTransformScale(transform, 2, 2);
CGAffineTransform t= CGAffineTransformRotate( tScale , 30 / 180.0 * M_PI );
CGAffineTransform t= CGAffineTransformRotate( tScale , 30 / 180.0 * M_PI );
3. 常用的函数和注意事项
命名规则是SHAPE
CGContextRef
context
=
UIGraphicsGetCurrentContext
(
);
1>
CGMutableSHAPE
Ref path = CGSHAPE
CreateMutable
();//创建
2>需要的绘画动作是CGSHAPE+动词
3>
CGContextAddSHAPE
(content, path);//将没有颜色等属性的图传入画布中
4>将形状着色或填充等[[
UIColor
blueColor
]
setStroke
];//描边
5>
CGContextDrawSHAPE
(context , kCGPathStroke);//选取用那种颜色填充,见备注
6>
CGSHAPE
Release
(path);//释放
4. 学习来源
iOS programming cook book