Graphics States
<wbr>在创建context的时候,都会创建一个空的stack用于存储graphics的状态。通过函数CGContextSaveGState和函数CGContextRestoreGState分别将graphics的状态压入和弹出stack。<br><wbr> graphics的状态不好看path,path数据不会存在stack中。<br><br><span style="font-weight:bold">Drawing to a View Graphics Contextin iOS</span><br><br><wbr>在iOS中绘画是在UIView中通过UIView的函数drawRect:来实现的。drawRect:函数在view在当前的屏幕上可见并且view的部分需要更新的时候才会被调用。<br><wbr> 注意:<br><wbr>1、drawRect:函数并不会自动被调用,一般在view可见的情况下,加载view的时候被调用一次,之后如果需要调用需要调用view的函数setNeedsDisplay或setNeedsDisplayRect(函数名忘了)的时候才会被调用。<br><wbr>2、调用drawRect:的时候,系统会自动的对绘画的环境进行设置,其中包括为当前的UIView建立一个context,也就是说在drawRect:函数外调用UIGraphicsGetCurrtentCon<wbr>text函数,无法获取当前的context<br><wbr> 3、Quartz是core graphics的总称,跟coregraphics采用的坐标系为LLO,UIView采用的是UIKit框架坐标轴为ULO,变换的时候通过CTM<br><br><span style="font-weight:bold">Anti-Aliasing(消除锯齿)</span><br><br><wbr> 消除锯齿的工作需要两步骤:<br><wbr> 1、将graphicscontext的状态设置为anti-aliasing。通过函数CGContextSetShouldAntial<wbr>ias<br><wbr>2、将context设置为anti-aliasing。通过函数CGContextSetAllowsAntial<wbr>iasing。true:allowinganti-aliasing; false: not to allow it。<br><br><span style="font-weight:bold">Creating a Path</span><br><br><wbr>在一个context中绘画,通过函数CGContextBeginPath开始。之后通过函数CGcontextMoveToPoint设置第一个点,在之后通过CGContextAddLine等函数添加更多的图形,最后通过fill或stroke函数将path画在context上。<br><wbr>例如:CGContextDrawPath(contextRef,kCGPathStroke)或CGContextStrokePath(context)<br><wbr> 注意:<br><wbr> 1、之前的一系列函数仅仅是构造path,并没有将path画在context上。<br><wbr>2、调用CGContextClip之前,path是不能fill或者stoke的,否则出不来clip的效果<br><wbr>与context构造path对应的,还可以通过CGPathRef的函数构造path,原理是相同的。画path的时候调用CGContextAddPath。<br><wbr>具体的path的参数请参考原文:https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_paths/dq_paths.html<br><wbr> 例如:画虚线,可以通过CGContextSetLineDash完成。<br><wbr>除此之外,画矩形、椭圆、线段还有一些更直接的函数,不需要先add,在stroke,可以直接调用下面的函数:<br><wbr> CGContextStrokePath<br><wbr> CGContextStrokeRect<br><wbr> CGContextStrokeRectWithW<wbr>idth<br><wbr> CGContextStrokeEllipseIn<wbr>Rect<br><wbr> CGContextStrokeLineSegme<wbr>nts(参数的形式:线段一起始点,线段一结束点,线段二起始点,线段二结束点···)<br><br><span style="font-weight:bold">Filling a Path</span><br><wbr> 此部分与上一部分差不多,直接参考原文。<br><br><span style="font-weight:bold">Setting Blend Modes</span><br><br><wbr> Blendmodes表示的是在一个背景上画画的时候,前后颜色是如何叠加的。正常情况下,绘图时Qutarz采用的时候默认的模式,显现的效果是通过下面的计算得到的:<br> result = (alpha * foreground) + (1 - alpha) * background<br><wbr> blend modes属于contextstates,可以通过CGContextSaveGState和CGContextRestoreGState在stack中保存和推出context的states。设置blendmode的方法是CGContextSetBlendMode。<br><br><span style="font-weight:bold">Clipping to a Path</span><br><br><wbr>此部分的意义在于将path作为mask来用,通过两个函数:CGContextClip和函数CGContextDrawImage,实现path经过的部分的图片被显现出来,未经过的部分则不显示。<br><wbr>此处与画线的不同之处在于用CGContextClip代替了画线的fill和stroke<br><br><span style="font-weight:bold">Transforms</span><br><br><wbr> 第一种方法:通过CTM<br><wbr> CGContextTranslateCTM<br><wbr> CGContextScaleCTM:x,y有负值,就代表了反方向<br><wbr> CGContextRotateCTM:-值代表了顺时针,正值代表了逆时针。弧度制<br><wbr> 其他方法原理相似,参考源文档<br><br><span style="font-weight:bold">Pattern</span><br><br><wbr> pattern在我看来就是图样、或叫模板。主要作用是设置context的fill或者strokepattern之后,context中调用fill或者stroke的时候用该pattern填充。<br><wbr> 首先,pattern分为两种:带色和不带色的。它们两个的区别主要体现在一下几个方面:<br><wbr> 1、建立callbackfunction的时候。color:指出fill或者stroke的颜色。stencil:不指出颜色,直接调用fill和stroke建立对应的cell,建立color的时候需要指出使用RGB的colorspace,这样方便后面用rgb对pattern着色。当然,针对color的pattern,完全可以采用一个图片来作为patterncell,那么直接将这个图片画在context就算是建立cell了,具体代码在后。<br><wbr> 2、color space的时候,stencile:指出color为RGB colorspace<br><wbr>3、设置采用当前的pattern填充的时候,调用CGContextSetFillPattern或者CGContextSetStrokePatter<wbr>n,对于stencile,需要指出采用的颜色的RGB值,意在着色。<br><wbr>4、在patterncreate,isColored设置为false对于stencile<br><wbr> 两种pattern使用的时候都是分为一下5个步骤:<br><wbr> 1、write a callback function that draw a coloredpattern cell<br><wbr> 2、set up the colored pattern color space<br><wbr> 3、set up the anatomy of the coloredpattern<br><wbr> 4、specify the colored pattern as a fill orstroke pattern<br><wbr> 5、draw with the colored pattern<br> 代码示例:<br> color:<br> void MyPatternDraw(void *info,CGContextRef contextRef)//1、patterncell callback function<br> {<br><wbr><wbr><wbr> UIImage*image = [UIImage imageNamed:@"2.png"];<br><wbr><wbr><wbr> CGImageRefimageRef = image.CGImage;<br><wbr><wbr><wbr> CGRect rect= CGRectMake(0, 0, CGImageGetWidth(imageRef),CGImageGetHeight(imageRef));<br><wbr><wbr><wbr><br><wbr><wbr><wbr>CGContextDrawImage(contextRef, rect, imageRef);<br> }<br> void MyColoredPatternDraw(CGContextRef contextRef,CGRectrect)//2,3,4,5<br> {<br><wbr><wbr><wbr> CGPatternRefpatternRef;<br><wbr><wbr><wbr>CGColorSpaceRef patternSpace;<br><wbr><wbr><wbr> float alpha= 1;<br><wbr><wbr><wbr> static constCGPatternCallbacks callbacks ={0,&MyPatternDraw,NULL};//参数:版本,开始话pattern的函数和最后释放空间的函数<br><wbr><wbr><wbr><br><wbr><wbr><wbr>CGContextSaveGState(contextRef);<br><wbr><wbr><wbr> patternSpace=CGColorSpaceCreatePatter<wbr>n(NULL);//这里为null,若为stencile,需简历一个rgb的colorspace,并作为这个函数的参数<br><wbr><wbr><wbr>CGContextSetFillColorSpa<wbr>ce(contextRef, patternSpace);<br><wbr><wbr><wbr>CGColorSpaceRelease(patternSpace);<br><wbr><wbr><wbr><br><wbr><wbr><wbr> patternRef =CGPatternCreate(NULL,<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>CGRectMake(0, 0, 41, 50), //pattern 的大小<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>CGAffineTransformMakeSca<wbr>le(1, -1),//通过这个可以对单个cell进行旋转,放大、缩小操作<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>60, 60,//pattern之间的上下间隔<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>kCGPatternTilingConstant<wbr>Spacing,<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>