【Quartz2D】
Quartz 2D is a two-dimensional drawing engine. 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 part of the Core Graphics framework, so you may see Quartz referred to as Core Graphics or, simply, CG.
【Graphics Contexts】
A graphics context represents a drawing destination. It contains drawing parameters and all device-specific information that the drawing system needs to perform any subsequent drawing commands.
A graphics context is represented by CGContextRef, which is an opaque data type.
【Window Graphics Contexts】
You obtain this graphics context in your drawRect: method by calling the UIKit function UIGraphicsGetCurrentContext in method
drawRect:.
In Mac You obtain a Quartz graphics context from within the drawRect: routine of a Cocoa application using the following line of code:
The method currentContext returns the NSGraphicsContext instance of the current thread. The method graphicsPort returns the low-level, platform-specific graphics context represented by the receiver, which is a Quartz graphics context. (Don’t get confused by the method names; they are historical.)
1 @implementation MyQuartzView 2 3 - (id)initWithFrame:(NSRect)frameRect 4 { 5 self = [super initWithFrame:frameRect]; 6 return self; 7 } 8 9 - (void)drawRect:(NSRect)rect 10 { 11 CGContextRef myContext = [[NSGraphicsContext // 1 12 currentContext] graphicsPort]; 13 // ********** Your drawing code here ********** // 2 14 CGContextSetRGBFillColor (myContext, 1, 0, 0, 1);// 3 15 CGContextFillRect (myContext, CGRectMake (0, 0, 200, 100 ));// 4 16 CGContextSetRGBFillColor (myContext, 0, 0, 1, .5);// 5 17 CGContextFillRect (myContext, CGRectMake (0, 0, 100, 200));// 6 18 } 19 20 @end
【Creating a Bitmap Graphics Context】
A bitmap graphics context accepts a pointer to a memory buffer that contains storage space for the bitmap. When you paint into the bitmap graphics context, the buffer is updated. After you release the graphics context, you have a fully updated bitmap in the pixel format you specify.
1 CGContextRef MyCreateBitmapContext (int pixelsWide, 2 int pixelsHigh) 3 { 4 CGContextRef context = NULL; 5 CGColorSpaceRef colorSpace; 6 void * bitmapData; 7 int bitmapByteCount; 8 int bitmapBytesPerRow; 9 10 bitmapBytesPerRow = (pixelsWide * 4);// 1 11 bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); 12 13 colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2 14 bitmapData = calloc( bitmapByteCount );// 3 15 if (bitmapData == NULL) 16 { 17 fprintf (stderr, "Memory not allocated!"); 18 return NULL; 19 } 20 context = CGBitmapContextCreate (bitmapData,// 4 21 pixelsWide, 22 pixelsHigh, 23 8, // bits per component 24 bitmapBytesPerRow, 25 colorSpace, 26 kCGImageAlphaPremultipliedLast); 27 if (context== NULL) 28 { 29 free (bitmapData);// 5 30 fprintf (stderr, "Context not created!"); 31 return NULL; 32 } 33 CGColorSpaceRelease( colorSpace );// 6 34 35 return context;// 7 36 }
【Anti-Aliasing】
Bitmap graphics contexts support anti-aliasing. You can turn anti-aliasing off for a particular bitmap graphics context by calling the function CGContextSetShouldAntialias. The anti-aliasing setting is part of the graphics state.
You can control whether to allow anti-aliasing for a particular graphics context by using the function CGContextSetAllowsAntialiasing. Pass true to this function to allow anti-aliasing; false not to allow it. This setting is not part of the graphics state. Quartz performs anti-aliasing when the context and the graphic state settings are set to true.
【Alpha】
In the normal blend mode (which is the default for the graphics state) Quartz performs alpha blending by combining the components of the source color with the components of the destination color using the formula:
destination = (alpha * source) + (1 - alpha) * destination
You can supply an alpha value as the last color component to all routines that accept colors. You can also set the global alpha value using the CGContextSetAlpha function. Keep in mind that if you set both, Quartz multiplies the alpha color component by the global alpha value.
【Shadow】
Shadows have three characteristics:
CGContextSetShadow、CGContextSetShadowWithColor
【Transparent Layer】
Quartz maintains a transparency layer stack for each context and transparency layers can be nested. But because layers are always part of a stack, you can’t manipulate them independently.
You signal the start of a transparency layer by calling the function CGContextBeginTransparencyLayer, which takes as parameters a graphics context and a CFDictionary object. The dictionary lets you provide options to specify additional information about the layer, but because the dictionary is not yet used by the Quartz 2D API, you pass NULL. After this call, graphics state parameters remain unchanged except for alpha (which is set to 1), shadow (which is turned off), blend mode (which is set to normal), and other parameters that affect the final composite.
After you begin a transparency layer, you perform whatever drawing you want to appear in that layer. Drawing operations in the specified context are drawn as a composite into a fully transparent backdrop. This backdrop is treated as a separate destination buffer from the context.
When you are finished drawing, you call the function CGContextEndTransparencyLayer. Quartz composites the result into the context using the global alpha value and shadow state of the context and respecting the clipping area of the context.
1 void MyDrawTransparencyLayer (CGContext myContext, // 1 2 CGFloat wd, 3 CGFloat ht) 4 { 5 CGSize myShadowOffset = CGSizeMake (10, -20);// 2 6 7 CGContextSetShadow (myContext, myShadowOffset, 10); // 3 8 CGContextBeginTransparencyLayer (myContext, NULL);// 4 9 // Your drawing code here// 5 10 CGContextSetRGBFillColor (myContext, 0, 1, 0, 1); 11 CGContextFillRect (myContext, CGRectMake (wd/3+ 50,ht/2 ,wd/4,ht/4)); 12 CGContextSetRGBFillColor (myContext, 0, 0, 1, 1); 13 CGContextFillRect (myContext, CGRectMake (wd/3-50,ht/2-100,wd/4,ht/4)); 14 CGContextSetRGBFillColor (myContext, 1, 0, 0, 1); 15 CGContextFillRect (myContext, CGRectMake (wd/3,ht/2-50,wd/4,ht/4)); 16 CGContextEndTransparencyLayer (myContext);// 6 17 }
【总结】
1. Quartz2D是一个2D的渲染引擎,是CoreGraphics框架的一部分。
2. Graphics Context是一个渲染目标,类型于OpenGL中的Framebuffer,与Framebuffer相比,Context还包含状态。
3. 有Window Context, PDF Context, BitmapContext, CGLayerContext(此Context依附于前3个Context)
/************Context属性***************/
4. 搞锯齿由Quartz2D自己实现,与OpenGL中一致,程序员可以做的就只有通过 CGContextSetShouldAntialias,CGContextSetAllowsAntialiasing 2个函数来设置Context是否启动抗锯齿。
5. 通过 CGContextSetAlpha 可以设置Context的Alpha(全局)。
6. 通过 CGContextSetShadow, CGContextSetShadowWithColor 可以设置Shadow。
7. 通过 CGContextSetBlendMode来设置绘制的颜色混合,避免先绘制了图1,后绘制图2,此函数设置如果混合图1与图2的颜色。
8. CGContextClip 使用当前Path设置ClipArea。
/************渲染工具***************/
9. 通过 CGContextBeginTransparencyLayer, CGContextEndTransparencyLayer 可以解决阴影问题。
10. 一个Context只有一个Path, Lines, arcs, and curves必须调用CGContextClosePath来关闭路径。
1) 通过 CGContextBeginPath,CGPathCreateMutable 来创建路径,CGContextAddPath 可以把创建好的Path加入到Context。
2) 通过 CGContextStrokePath, CGContextFillPath 可以绘制Context中的惟一路径。
11. CGLayer是个Buffer,依赖于每一个独立的Context。CGLayerCreateWithContext可以创建layer,CGLayerGetContext获取layer的context进行绘制,CGContextDrawLayerInRect, CGContextDrawLayerAtPoint 绘制layer到点。
/************图片操作***************/
11.图片操作
1) 通过 CGImageCreate 等函数可以创建图片,CGImageCreateWithMask 可以创建mask,一个mask可以被应用到一个图片上。
2) 通过 CGImageSourceCreateWithURL 等函数来创建ImageSource,通过CGImageSourceCreateImageAtIndex 从ImageSource中取出图片。
3) 通过CGBitmapContextCreateImage可以从把Context中内容导出为Image。CGContextDrawImage 可以把图片绘制到Context中。
/************最后**************/
从drawRect函数来看,UIKit底层的渲染是由Quartz2D渲染引擎来完成,其中主要使用绘制Primitive,位图与应用clip。