IOS 画图--2
来源:互联网 发布:面料排版软件 编辑:程序博客网 时间:2024/04/29 21:01
CGPathDrawingMode
我们会根据drawingMode的五个常量讨论
kCGPathFill
, kCGPathEOFill
, kCGPathStroke
, kCGPathFillStroke
,or kCGPathEOFillStroke
.
(1)kCGPathFill如下图:
此fill模式为缺省模式(非零缠绕数原则),大概规则为,在需要填充颜色的区域的一点向画区域外画一条线,g如果是从左向右穿过的,则加1,如果从右向左穿过,则减一,最后结果为0则不fill,大于0则填充,所以line的方向对fill的区域有影响。
还有一种为even-odd(奇偶原则),只计算line穿过path段的个数,为偶数时,不填充,奇数时填充,所以path的方向不会影响填充的结果。
(2) kCGPathEOFill
模式
此填充模式为奇偶模式
(3)kCGPathStroke模式
(4)kCGPathFillStroke模式
(5)kCGPathEOFillStroke模式
例如: CGContextSetLineWidth(context, 2);
// CGContextSetLineDash(context, 0, NULL, 0);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 60.0, 10.0);
CGPathAddLineToPoint(path, NULL, 100.0, 100.0);
CGPathAddLineToPoint(path, NULL, 10.0, 50.0);
CGPathAddLineToPoint(path, NULL, 110.0, 50.0);
CGPathAddLineToPoint(path, NULL, 30.0, 100.0);
CGPathAddLineToPoint(path, NULL, 60.0, 10.0);
CGPathMoveToPoint(path, NULL, 260.0, 10.0);
CGPathAddLineToPoint(path, NULL, 220.0, 50.0);
CGPathAddLineToPoint(path, NULL, 238.0, 90.0);
CGPathAddLineToPoint(path, NULL, 282.0, 90.0);
CGPathAddLineToPoint(path, NULL, 300.0, 50.0);
CGPathAddLineToPoint(path, NULL, 260.0, 10.0);
/*1种*/ /*2种*/
CGPathMoveToPoint(path, NULL, 260.0, 20.0); //CGPathMoveToPoint(path, NULL, 260.0, 20.0);
CGPathAddLineToPoint(path, NULL, 230.0, 50.0); //CGPathAddLineToPoint(path, NULL, 290.0, 50.0);
CGPathAddLineToPoint(path, NULL, 248.0, 80.0); //CGPathAddLineToPoint(path, NULL, 272.0, 80.0);
CGPathAddLineToPoint(path, NULL, 272.0, 80.0); //CGPathAddLineToPoint(path, NULL, 248.0, 80.0);
CGPathAddLineToPoint(path, NULL, 290.0, 50.0); //CGPathAddLineToPoint(path, NULL, 230.0, 50.0);
CGPathAddLineToPoint(path, NULL, 260.0, 20.0); //CGPathAddLineToPoint(path, NULL, 260.0, 20.0);
CGContextAddPath(context, path);
CGContextSetFillColorWithColor(context, [UIColor colorWithRGBInt:0x00a400 alpha:1.0].CGColor);
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRGBInt:0xff0000 alpha:1.0].CGColor);
CGContextDrawPath(context, kCGPathEOFillStroke);///*1*/描边加两个5边型未重叠区域。/*2*/描边加两个5边型未重叠区域
//CGContextDrawPath(context, kCGPathEOFillStroke);///*1*/描边加55边型内部区域。/*2*/描边加两个5边型未重叠区域
CGContextSetLineWidth(context, 2);
CGPathRelease(path);
Graphics States
在创建context的时候,都会创建一个空的stack用于存储graphics的状态。通过函数CGContextSaveGState和函数CGContextRestoreGState分别将graphics的状态压入和弹出stack。
graphics的状态不好看path,path数据不会存在stack中。
Drawing to a View Graphics Contextin iOS
在iOS中绘画是在UIView中通过UIView的函数drawRect:来实现的。drawRect:函数在view在当前的屏幕上可见并且view的部分需要更新的时候才会被调用。
注意:
1、drawRect:函数并不会自动被调用,一般在view可见的情况下,加载view的时候被调用一次,之后如果需要调用需要调用view的函数setNeedsDisplay或setNeedsDisplayRect(函数名忘了)的时候才会被调用。
2、调用drawRect:的时候,系统会自动的对绘画的环境进行设置,其中包括为当前的UIView建立一个context,也就是说在drawRect:函数外调用UIGraphicsGetCurrtentContext函数,无法获取当前的context
3、Quartz是core graphics的总称,跟coregraphics采用的坐标系为LLO,UIView采用的是UIKit框架坐标轴为ULO,变换的时候通过CTM
Anti-Aliasing(消除锯齿)
消除锯齿的工作需要两步骤:
1、将graphicscontext的状态设置为anti-aliasing。通过函数CGContextSetShouldAntialias
2、将context设置为anti-aliasing。通过函数CGContextSetAllowsAntialiasing。true:allowinganti-aliasing; false: not to allow it。
Creating a Path
在一个context中绘画,通过函数CGContextBeginPath开始。之后通过函数CGcontextMoveToPoint设置第一个点,在之后通过CGContextAddLine等函数添加更多的图形,最后通过fill或stroke函数将path画在context上。
例如:CGContextDrawPath(contextRef,kCGPathStroke)或CGContextStrokePath(context)
注意:
1、之前的一系列函数仅仅是构造path,并没有将path画在context上。
2、调用CGContextClip之前,path是不能fill或者stoke的,否则出不来clip的效果
与context构造path对应的,还可以通过CGPathRef的函数构造path,原理是相同的。画path的时候调用CGContextAddPath。
具体的path的参数请参考原文:https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_paths/dq_paths.html
例如:画虚线,可以通过CGContextSetLineDash完成。
除此之外,画矩形、椭圆、线段还有一些更直接的函数,不需要先add,在stroke,可以直接调用下面的函数:
CGContextStrokePath
CGContextStrokeRect
CGContextStrokeRectWithWidth
CGContextStrokeEllipseInRect
CGContextStrokeLineSegments(参数的形式:线段一起始点,线段一结束点,线段二起始点,线段二结束点···)
Filling a Path
此部分与上一部分差不多,直接参考原文。
Setting Blend Modes
Blendmodes表示的是在一个背景上画画的时候,前后颜色是如何叠加的。正常情况下,绘图时Qutarz采用的时候默认的模式,显现的效果是通过下面的计算得到的:
result = (alpha * foreground) + (1 - alpha) * background
blend modes属于contextstates,可以通过CGContextSaveGState和CGContextRestoreGState在stack中保存和推出context的states。设置blendmode的方法是CGContextSetBlendMode。
Clipping to a Path
此部分的意义在于将path作为mask来用,通过两个函数:CGContextClip和函数CGContextDrawImage,实现path经过的部分的图片被显现出来,未经过的部分则不显示。
此处与画线的不同之处在于用CGContextClip代替了画线的fill和stroke
Transforms
第一种方法:通过CTM
CGContextTranslateCTM
CGContextScaleCTM:x,y有负值,就代表了反方向
CGContextRotateCTM:-值代表了顺时针,正值代表了逆时针。弧度制
其他方法原理相似,参考源文档
Pattern
pattern在我看来就是图样、或叫模板。主要作用是设置context的fill或者strokepattern之后,context中调用fill或者stroke的时候用该pattern填充。
首先,pattern分为两种:带色和不带色的。它们两个的区别主要体现在一下几个方面:
1、建立callbackfunction的时候。color:指出fill或者stroke的颜色。stencil:不指出颜色,直接调用fill和stroke建立对应的cell,建立color的时候需要指出使用RGB的colorspace,这样方便后面用rgb对pattern着色。当然,针对color的pattern,完全可以采用一个图片来作为patterncell,那么直接将这个图片画在context就算是建立cell了,具体代码在后。
2、color space的时候,stencile:指出color为RGB colorspace
3、设置采用当前的pattern填充的时候,调用CGContextSetFillPattern或者CGContextSetStrokePattern,对于stencile,需要指出采用的颜色的RGB值,意在着色。
4、在patterncreate,isColored设置为false对于stencile
两种pattern使用的时候都是分为一下5个步骤:
1、write a callback function that draw a coloredpattern cell
2、set up the colored pattern color space
3、set up the anatomy of the coloredpattern
4、specify the colored pattern as a fill orstroke pattern
5、draw with the colored pattern
代码示例:
color:
void MyPatternDraw(void *info,CGContextRef contextRef)//1、patterncell callback function
{
UIImage*image = [UIImage imageNamed:@"2.png"];
CGImageRefimageRef = image.CGImage;
CGRect rect= CGRectMake(0, 0, CGImageGetWidth(imageRef),CGImageGetHeight(imageRef));
CGContextDrawImage(contextRef, rect, imageRef);
}
void MyColoredPatternDraw(CGContextRef contextRef,CGRectrect)//2,3,4,5
{
CGPatternRefpatternRef;
CGColorSpaceRef patternSpace;
float alpha= 1;
static constCGPatternCallbacks callbacks ={0,&MyPatternDraw,NULL};//参数:版本,开始话pattern的函数和最后释放空间的函数
CGContextSaveGState(contextRef);
patternSpace=CGColorSpaceCreatePattern(NULL);//这里为null,若为stencile,需简历一个rgb的colorspace,并作为这个函数的参数
CGContextSetFillColorSpace(contextRef, patternSpace);
CGColorSpaceRelease(patternSpace);
patternRef =CGPatternCreate(NULL,
CGRectMake(0, 0, 41, 50), //pattern 的大小
CGAffineTransformMakeScale(1, -1),//通过这个可以对单个cell进行旋转,放大、缩小操作
60, 60,//pattern之间的上下间隔
kCGPatternTilingConstantSpacing,