iOS开发(高级特性)——Quartz2D

What is Quartz2D

UIView及其子类的应用目前比较熟悉了,下面开始学习一下Quartz2D。我们从名字上来大致猜测一下这个东西是干吗的,2D好说应该是说的2维和3D不同。那么Quartz又是个啥呢?Quartz的本意是石英石,也有石英表的意思。在Java中有个叫Quartz的开源的作业调度框架,估计是取其石英表的含义。但是在苹果开发中,这个名字到底怎么解释,还真猜不到。本来想望文知意的,结果不太靠谱,那我们直接先看一看苹果对Quartz 2D的描述

Quartz 2D is an advanced, two-dimensional drawing engine available for iOS application development and to all Mac OS X application environments outside of the kernel. Quartz 2D provides low-level, lightweight 2D rendering with unmatched output fidelity regardless of display or printing device. Quartz 2D is resolution- and device-independent; you don’t need to think about the final destination when you use the Quartz 2D application programming interface (API) for drawing.

The Quartz 2D API is easy to use and provides access to powerful features such as transparency layers, path-based drawing, offscreen rendering, advanced color management, anti-aliased rendering, and PDF document creation, display, and parsing.

The Quartz 2D API is part of the Core Graphics framework, so you may see Quartz referred to as Core Graphics or, simply, CG

这么一大段话,我们找几个关键字:drawing engine, resolution, device-independent, API。

这几个关键词加起来就是说,我们可以调用Quartz 2D的接口来绘图。至于后面的简单易用,功能强大这一类的描述,看看就好,不必较真。

我们已经知道了Quartz2D是什么,也知道它能干什么,接下来就是学习它是怎么做的。

When to use Quartz2D

讨论怎么用之前,我们先了解一下什么时候用,即应用场景。还是看苹果给的东西吧,毕竟这玩意都是他们搞出来的。

Draw graphics

Provide graphics editing capabilities in an application

Create or display bitmap images

Work with PDF documents

对这上面这几种翻译一下:

1 )画图

这里说的画图,应该是指在界面上画线条,多边形,弧形等。如股票软件中的各种线条。

2)提供图形编辑功能

图片编辑功能复杂一点,如照片处理一类的。

3)创建或者显示位图

4)处理PDF文档

How to use Quartz2D


concept

我们先理解一些概念,不然理解后面说的东西比较费劲。

1)Painter's model


iOS开发(高级特性)——Quartz2D_第1张图片
图1

看图1来理解这个所谓的粉刷模型,就是一个粉刷效果,后面的掩盖前面的。

2)The Graphics Context

这个可以理解为绘画环境,比如涂鸦绘画环境就是墙壁,油画的绘画环境就是画布。开发中的绘画环境有:位图,PDF,窗口,图层。

Creating a Window Graphics Context,API本身不能获取window的Context,需要在Cocoa framework中获取一个。

CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];//

Creating a PDF Graphics Context

CGPDFContextCreateWithURL

CGPDFContextCreate

Creating a Bitmap Graphics Context

CGBitmapContextCreate

UIGraphicsBeginImageContextWithOptions//iOS环境中用这个,避免坐标系统的不同

3)Opaque Data Types

数据类型很多,我们用到的时候在详细了解。下面列一下这些数据类型和用处:

CGPathRef, used for vector graphics to create paths that you fill or stroke. SeePaths.

CGImageRef, used to represent bitmap images and bitmap image masks based on sample data that you supply. SeeBitmap Images and Image Masks.

CGLayerRef, used to represent a drawing layer that can be used for repeated drawing (such as for backgrounds or patterns) and for offscreen drawing. SeeCore Graphics Layer Drawing

CGPatternRef, used for repeated drawing. SeePatterns.

CGShadingRefandCGGradientRef, used to paint gradients. SeeGradients.

CGFunctionRef, used to define callback functions that take an arbitrary number of floating-point arguments. You use this data type when you create gradients for a shading. SeeGradients.

CGColorRefandCGColorSpaceRef, used to inform Quartz how to interpret color. SeeColor and Color Spaces.

CGImageSourceRefandCGImageDestinationRef, which you use to move data into and out of Quartz. SeeData Management in Quartz 2DandImage I/O Programming Guide.

CGFontRef, used to draw text. SeeText.

CGPDFDictionaryRef,CGPDFObjectRef,CGPDFPageRef,CGPDFStream,CGPDFStringRef,andCGPDFArrayRef, which provide access to PDF metadata. SeePDF Document Creation, Viewing, and Transforming.

CGPDFScannerRefandCGPDFContentStreamRef, which parse PDF metadata. SeePDF Document Parsing.

CGPSConverterRef, used to convert PostScript to PDF. It is not available in iOS. SeePostScript Conversion.

4)Coordinate Systems

在二维中绘图,坐标系的概念必不可少。指标系统大家还是比较熟悉的,过多的解释没有必要,值得注意的是在iOS的显示中坐标原点的位置不在左下角而在左上角。

5)Path

我们想要画一个三角形或一个圆,在现实中我们可以根据抽象的思维,随意画出三角形和圆,但是计算机怎样能够准确的画出我们想要的图案呢。Path就是用来定义图形的。可以理解为Path表示了图形的轮廓,按照这个轮廓,通过填充,描绘就可以准确的得到我们想要的图案。

直接在Context上画

CGContextMoveToPoint

CGContextAddLineToPoint

CGContextAddLines

CGContextAddArc

CGContextAddArcToPoint

CGContextAddCurveToPoint

CGContextAddQuadCurveToPoint

CGContextClosePath

CGContextAddEllipseInRect

CGContextAddRect

创建可复用的Path

CGPathCreateMutable, which replacesCGContextBeginPath

CGPathMoveToPoint, which replacesCGContextMoveToPoint

CGPathAddLineToPoint, which replacesCGContextAddLineToPoint

CGPathAddCurveToPoint, which replacesCGContextAddCurveToPoint

CGPathAddEllipseInRect, which replacesCGContextAddEllipseInRect

CGPathAddArc, which replacesCGContextAddArc

CGPathAddRect, which replacesCGContextAddRect

CGPathCloseSubpath, which replacesCGContextClosePath

将Path加到Context上CGContextAddPath.

有了Path了我们就可以涂鸦啦,哦不对,是Paint.有两种方式,填充(filling)和笔画(stroking)。

Parameters That Affect Stroking

Parameter:Function to set parameter value

Line width:CGContextSetLineWidth//线宽度

Line join:CGContextSetLineJoin//连接处的风格设置

Line cap:CGContextSetLineCap//两端的风格

Miter limit:CGContextSetMiterLimit //

Line dash pattern:CGContextSetLineDash

Stroke color space:CGContextSetStrokeColorSpace

Stroke color:CGContextSetStrokeColorCGContextSetStrokeColorWithColor

Stroke pattern:CGContextSetStrokePattern

Functions that fill paths

CGContextEOFillPath

Fills the current path using the even-odd rule.

CGContextFillPath

Fills the current path using the nonzero winding number rule.

CGContextFillRect

Fills the area that fits inside the specified rectangle.

CGContextFillRects

Fills the areas that fits inside the specified rectangles.

CGContextFillEllipseInRect

Fills an ellipse that fits inside the specified rectangle.

CGContextDrawPath

Fills the current path if you pass kCGPathFill(nonzero winding number rule) or kCGPathEOFill(even-odd rule). Fills and strokes the current path if you pass kCGPathFillStroke or kCGPathEOFillStroke.

6)Color and Color Space

颜色的相关内容。

7) Transform

如图,Transform说的就是这样的一些变换。缩放、移动,旋转等。有坐标系作为基础,这些变化对应相应的数学知识就很好理解了。简单的直接调用API即可,复杂的变换可能要涉及到数学内容,比如矩阵变换等,这些东西不在讨论范围。明白可能用到这些就好了

iOS开发(高级特性)——Quartz2D_第2张图片
iOS开发(高级特性)——Quartz2D_第3张图片


8)Partterns


9)Shadows

阴影可以让2D的图形有3D的视觉效果。

10)Gradient

有时候一种颜色,或者简单叠加的颜色看起来很枯燥乏味,我们用渐变让图形更丰富。

理解了这些东西了,也很无聊的了,来个例子吧,看看这些东西到底是怎么玩的。

@implementation MyQuartzView

- (id)initWithFrame:(NSRect)frameRect

{

self = [super initWithFrame:frameRect];

return self;

}

- (void)drawRect:(NSRect)rect

{

CGContextRef myContext = [[NSGraphicsContext

currentContext] graphicsPort]; // 1

// ********** Your drawing code here **********// 2

CGContextSetRGBFillColor (myContext, 1, 0, 0, 1);// 3

CGContextFillRect (myContext, CGRectMake (0, 0, 200, 100 ));// 4

CGContextSetRGBFillColor (myContext, 0, 0, 1, .5);// 5

CGContextFillRect (myContext, CGRectMake (0, 0, 100, 200));// 6

}

@end

得到的效果如图2

1.获取Context

2.准备绘图

3.设置填充颜色(涉及到Color相关内容)

4.填充矩形区域(涉及到path相关内容)

5.再次设置颜色(透明相关)

6.填充矩形区域(根据Painter's Model 覆盖,重叠区域的覆盖)

iOS开发(高级特性)——Quartz2D_第4张图片
图2


Demo

1)QuartzLines

简单画线


-(void)drawInContext:(CGContextRef)context

{

// Drawing lines with a white stroke color

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);

// Draw them with a 2.0 stroke width so they are a bit more visible.

CGContextSetLineWidth(context, 2.0);

// Draw a single line from left to right

CGContextMoveToPoint(context, 10.0, 30.0);

CGContextAddLineToPoint(context, 310.0, 30.0);

CGContextStrokePath(context);

// Draw a connected sequence of line segments

CGPoint addLines[] =

{

CGPointMake(10.0, 90.0),

CGPointMake(70.0, 60.0),

CGPointMake(130.0, 90.0),

CGPointMake(190.0, 60.0),

CGPointMake(250.0, 90.0),

CGPointMake(310.0, 60.0),

};

// Bulk call to add lines to the current path.

// Equivalent to MoveToPoint(points[0]); for(i=1; i < count,++i) AddLineToPoint(points[i]);

CGContextAddLines(context, addLines, sizeof(addLines)/sizeof(addLines[0]));

CGContextStrokePath(context);

CGPoint strokeSegments[] =

{

CGPointMake(10.0, 150.0),

CGPointMake(70.0, 120.0),

CGPointMake(130.0, 150.0),

CGPointMake(190.0, 120.0),

CGPointMake(250.0, 150.0),

CGPointMake(310.0, 120.0),

};

// Bulk call to stroke a sequence of line segments.

CGContextStrokeLineSegments(context, strokeSegments, sizeof(strokeSegments)/sizeof(strokeSegments[0]));  

iOS开发(高级特性)——Quartz2D_第5张图片

cap and join

-(void)drawInContext:(CGContextRef)context

{

// Drawing lines with a white stroke color

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);

// Preserve the current drawing state

CGContextSaveGState(context);

// Setup the horizontal line to demostrate caps

CGContextMoveToPoint(context, 40.0, 30.0);

CGContextAddLineToPoint(context, 280.0, 30.0);

// Set the line width & cap for the cap demo

CGContextSetLineWidth(context, self.width);

CGContextSetLineCap(context, self.cap);

CGContextStrokePath(context);

// Restore the previous drawing state, and save it again.

CGContextRestoreGState(context);

CGContextSaveGState(context);

// Setup the angled line to demonstrate joins

CGContextMoveToPoint(context, 40.0, 190.0);

CGContextAddLineToPoint(context, 160.0, 70.0);

CGContextAddLineToPoint(context, 280.0, 190.0);

// Set the line width & join for the join demo

CGContextSetLineWidth(context, self.width);

CGContextSetLineJoin(context, self.join);

CGContextStrokePath(context);

// Restore the previous drawing state.

CGContextRestoreGState(context);

// If the stroke width is large enough, display the path that generated these lines

if (self.width >= 4.0) // arbitrarily only show when the line is at least twice as wide as our target stroke

{

CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

CGContextMoveToPoint(context, 40.0, 30.0);

CGContextAddLineToPoint(context, 280.0, 30.0);

CGContextMoveToPoint(context, 40.0, 190.0);

CGContextAddLineToPoint(context, 160.0, 70.0);

CGContextAddLineToPoint(context, 280.0, 190.0);

CGContextSetLineWidth(context, 2.0);

CGContextStrokePath(context);

}

}

-(void)setCap:(CGLineCap)c

{

if(c != _cap)

{

_cap = c;

[self setNeedsDisplay];

}

}

-(void)setJoin:(CGLineJoin)j

{

if(j != _join)

{

_join = j;

[self setNeedsDisplay];

}

}

-(void)setWidth:(CGFloat)w

{

if(w != _width)

{

_width = w;

[self setNeedsDisplay];

}

}



iOS开发(高级特性)——Quartz2D_第6张图片
iOS开发(高级特性)——Quartz2D_第7张图片

2)QuartzPoly

3)QuartzGradient

4)QuartzDash

5)QuartzPolygons

6)QuartzCurves

7)QuartzImages

8)QuartzRendering

9) QuartzClipping

2到9的内容就不一一贴代码和贴图了。这些内容不用记得太清楚,用的时候有个印象能快速查询到相关文档既可以了。

你可能感兴趣的:(iOS开发(高级特性)——Quartz2D)