|
Quartz 2D 编程指导
简介:
1.更为底层的开发API,相比较Core Animation
框架
2.是一个2D的作图引擎
3.它独立于分辨率和设备
4.它是Core Graphic框架的一部分,大部分类都是以CG-开头
目的:
-
Draw graphics
-
Provide graphics editing capabilities in an application
-
Create or display bitmap images
-
Work with PDF documents
如果开发任务与以上四点无关,那么Quartz 2D 就不是太有意义
接来下说说学习的主要内容:
1.概要部分
页(Canvas),画图的地方,Quartz 使用的不透明的数据类型,图像状态,坐标系,内存管理
2.Context
描述了几种画图地方的类别,以及如何创建不同种类的Context
你只要记住,所有的作图都必须在context里面,它就像画家的画板一样
3.Paths
描述了Path构成的元素,怎样去创建Path,描画Path,设置裁剪区域,混合模式(Blend Mode)怎样影响描绘的效果
4.Color&Color Space
讨论色值,以及透明层的alpha属性,描述了怎么创建color space,设置color,创建color对象,设置rendering intent
5.Transforms
描述了CTM(当前变换矩阵),怎么修改它,展示了怎么设置affine transform,怎么在user space和device space 之间转换,还有一点数学背景知识
6.Patterns
定义了什么是pattern和pattern的组成部分,Quartz是怎么渲染pattern的,以及如何创建Colored pattern和Stenciled pattern
7.Shadows
定义了shadow是什么,解释了shadow是怎么工作的,以及怎么描绘shadow
8.Gradients
讨论了,轴向和辐射状的gradient,展示了怎么创建CGShading和CGGradient对象
9.Transparent Layers
告诉Transparent Layer是什么样子,讨论Transparent Layer怎么工作的,以及step-by-step的实现
10.Data Management
告诉数据是怎么从Quartz 中输入、输出
11.Bitmap images & images mask
定义了bitmap,怎么为Quartz初始化一个bitmap image,给images加上掩码,展示了当在描绘image时各种混合模式能够达到的效果
12.Core Graphic Layer Drawing
描述了怎么创建和描绘Layer,已达到高性能的pattern描绘或者是offscreen描绘
13.PDF Document Creation,Viewing,Transforming
讨论了如何访问PDF的metadata,添加links,增加安全特性(密码保护)
14.PDF Document Parsing
描述了怎么通过CGPDFScanner
和 CGPDFContentStream对象来解析和查看PDF Document
15.PostScript Conversion
讨论了将PostScript转化成PDF(Only in Mac OS X)
16.Text
这部分还是看Core Text 框架吧
开始第一部分:
1.1 Quartz 使用了painter’s model
![Screen Shot 2016-01-03 at 14.23.43.png]()
1.2 Drawing Destinations: The Graphics Context
Context的种类有:
-
A bitmap graphics context allows you to paint RGB colors, CMYK colors, or grayscale into a bitmap.
-
A PDF graphics context allows you to create a PDF file.
-
A window graphics context is a graphics context that you can use to draw into a window.
-
Note that because Quartz 2D is a graphics engine and not a window management system, you use one of the application frameworks to obtain a graphics context for a window.
-
A layer context (CGLayerRef) is an offscreen drawing destination associated with another graphics context. It is designed for optimal performance when drawing the layer to the
graphics context that created it. A layer context can be a much better choice for offscreen drawing than a bitmap graphics context.
-
When you want to print in Mac OS X, you send your content to a PostScript graphics context that is managed by the printing framework.
1.3 Quartz 2D Opaque Data Types
The opaque data types available in Quartz 2D include the following:
-
CGPathRef, used for vector graphics to create paths that you fill or stroke.
-
CGImageRef, used to represent bitmap images and bitmap image masks based on sample data that
you supply.
-
CGLayerRef, used to represent a drawing layer that can be used for repeated drawing (such
as for backgrounds or patterns) and for offscreen drawing.
-
CGPatternRef, used for repeated drawing.
-
CGShadingRef and
CGGradientRef, used to paint gradients.
-
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.
-
CGColorRef and
CGColorSpaceRef, used to inform Quartz how to interpret color.
-
CGImageSourceRef and
CGImageDestinationRef, which you use to move data into and out of Quartz.
-
CGFontRef, used to draw text.
-
CGPDFDictionaryRef,
CGPDFObjectRef,
CGPDFPageRef,
CGPDFStream,
CGPDFStringRef, and
CGPDFArrayRef, which provide access to PDF metadata.
-
CGPDFScannerRef and
CGPDFContentStreamRef, which parse PDF metadata.
-
CGPSConverterRef, used to convert PostScript to PDF. It is not available in iOS.
1.4 Graphics States
Quartz 是基于状态机制的
当你Save,相当于push了new state到当前的Context中,它会影响你之后在这个Context中的描绘操作,除非你使用Restore,相当于从Context中Pop了之前的state,但并不是所有的描绘环境都受到State的影响,以下是参考表:
![Screen Shot 2016-01-03 at 14.39.13.png]()
1.5 Quartz 2D Coordinate Systems
![quartz_coordinates.gif]()
在以下地方要注意坐标系的不同:
-
In Mac OS X, a subclass of
NSView that overrides its method to return
YES.
-
In iOS, a drawing context returned by an
UIView.
-
In iOS, a drawing context created by calling the
UIGraphicsBeginImageContextWithOptions function.
注意在iOS中,pattern和shadow是不受CTM的影响,也就是不需要反转坐标系。
1.6Memory Management: Object Ownership
内存管理的规则就是MRC的原则
2.Graphic Context
在iOS中描绘,在View的Context中操作,需要重载drawRect:,并使用UIGraphicsGetCurrentContext方法获取当前的Context
在Mac OS X中描绘,在Window的Context中操作,需要重载drawRect:但是要用:
CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];
来获取Context
,因为关于window的Context,Quartz API不提供获取方法
创建PDF Context:
![Screen Shot 2016-01-03 at 14.58.30.png]() ![Screen Shot 2016-01-03 at 14.58.19.png]()
创建Bitmap Graphic Context
You use the function
CGBitmapContextCreate to create a bitmap graphics context. This function takes the following parameters:
-
data. Supply a pointer to the destination in memory where you want the drawing rendered.
The size of this memory block should be at least (bytesPerRow*height) bytes.
-
width. Specify the width, in pixels, of the bitmap.
-
height. Specify the height, in pixels, of the bitmap.
-
bitsPerComponent. Specify the number of bits to use for each component of a pixel in memory.
For example, for a 32-bit pixel format and an RGB color space, you would specify a value of 8 bits per component.
-
bytesPerRow. Specify the number of bytes of memory to use per row of the bitmap.Tip:
When you create a bitmap graphics context, you’ll get the best performance if you make sure the data and
bytesPerRow are 16-byte aligned.
-
colorspace. The color space to use for the bitmap context. You can provide a Gray, RGB,
CMYK, or NULL color space when you create a bitmap graphics context. For detailed information on color spaces and color management principles, see a target="_self" Color Management Overview/a. For information on creating and using color spaces in Quartz
-
bitmapInfo. Bitmap layout information, expressed as a
CGBitmapInfo constant, that specifies whether the bitmap should contain an alpha component, the relative location of the alpha component (if there is one) in a pixel, whether
the alpha component is premultiplied, and whether the color components are integer or floating-point values. For detailed information on what these constants are, when each is used, and Quartz-supported pixel form
|
Listing 2-5 Creating a bitmap graphics context
|
CGContextRef MyCreateBitmapContext (int pixelsWide,
|
|
int pixelsHigh)
|
|
{
|
|
CGContextRef context = NULL;
|
|
CGColorSpaceRef colorSpace;
|
|
void * bitmapData;
|
|
int bitmapByteCount;
|
|
int bitmapBytesPerRow;
|
|
|
|
bitmapBytesPerRow = (pixelsWide * 4);
// 1
|
|
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
|
|
|
|
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
// 2
|
|
bitmapData = calloc( bitmapByteCount );
// 3
|
|
if (bitmapData == NULL)
|
|
{
|
|
fprintf (stderr, "Memory not allocated!");
|
|
return NULL;
|
|
}
|
|
context = CGBitmapContextCreate (bitmapData,
// 4
|
|
pixelsWide,
|
|
pixelsHigh,
|
|
8, // bits per component
|
|
bitmapBytesPerRow,
|
|
colorSpace,
|
|
kCGImageAlphaPremultipliedLast);
|
|
if (context== NULL)
|
|
{
|
|
free (bitmapData);
// 5
|
|
fprintf (stderr, "Context not created!");
|
|
return NULL;
|
|
}
|
|
CGColorSpaceRelease( colorSpace );
// 6
|
|
|
|
return context;
// 7
|
|
}
|
|
Listing 2-6 Drawing to a bitmap graphics context
|
CGRect myBoundingBox;
// 1
|
|
|
|
myBoundingBox = CGRectMake (0, 0, myWidth, myHeight);
// 2
|
|
myBitmapContext = MyCreateBitmapContext (400, 300);
// 3
|
|
// ********** Your drawing code here **********
// 4
|
|
CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1);
|
|
CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 ));
|
|
CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5);
|
|
CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 ));
|
|
myImage = CGBitmapContextCreateImage (myBitmapContext);
// 5
|
|
CGContextDrawImage(myContext, myBoundingBox, myImage);
// 6
|
|
char *bitmapData = CGBitmapContextGetData(myBitmapContext);
// 7
|
|
CGContextRelease (myBitmapContext);
// 8
|
|
if (bitmapData) free(bitmapData);
// 9
|
|
CGImageRelease(myImage);
|
Anti-Aliasing
通过函数CGContextSetAllowsAntialiasing.来设置是不是要锯齿效果
![antialias.jpg]()
3.Paths
各种复杂的图表,图形,图像,大部分都是可以通过构造Path, stroke、fill,然后描绘出来
Figure 3-1 Quartz supports path-based drawing
![path_vector_examples.gif]()
Path的创建和Path的描绘是独立的
Figure 3-2 A path that contains two shapes, or subpaths
![subpaths.gif]()
Figure 3-3 A clipping area constrains drawing
![circle_clipping.gif]()
Path的构成部分
Point:CGContextMoveToPoint
Lines:CGContextAddLineToPoint,CGContextAddLines
Arcs:CGContextAddArc,CGContextAddArcToPoint
Curves:CGContextAddCurveToPoint,CGContextAddQuadCurveToPoint
A cubic Bézier curve uses two control points
![cubic_bezier_curve.gif]()
A quadratic Bézier curve uses one control point
![quadratic_bezier_curve.gif]()
有时候为了要闭合的Path,则需要使用:
CGContextClosePath,会从subpath的start point连接一个新的path
Ellipses:CGContextAddEllipseInRect
Multiple paths; each path contains a randomly generated ellipse
![ellipses.gif]()
Rectangles:CGContextAddRect
Multiple paths; each path contains a randomly generated rectangle
![rectangles.gif]()
创建Path
first point, you can add lines, arcs, and curves to the path, keeping in mind the following:
-
Before you begin a new path, call the function
CGContextBeginPath.
-
Lines, arcs, and curves are drawn starting at the current point. An empty path has no current point; you must call
CGContextMoveToPoint to set the starting point for the first subpath or call a convenience function that implicitly does this for you.
-
When you want to close the current subpath within a path, call the function
CGContextClosePath to connect a segment to the starting point of the subpath. Subsequent path calls begin a new subpath, even if you do not explicitly set a new starting point.
-
When you draw arcs, Quartz draws a line between the current point and the starting point of the arc.
-
Quartz routines that add ellipses and rectangles add a new closed subpath to the path.
-
You must call a painting function to fill or stroke the path because creating a path does not draw the path. See
Painting a Path for detailed information
当你创建了Path,如果你不想在描绘之后就释放这样的对象,你需要使用前排的函数来创建一个可供修改的Path
The path functions operate on a CGPath object instead of a graphics context. These functions are:
-
CGPathCreateMutable, which replacesCGContextBeginPath
-
CGPathMoveToPoint, which replaces
CGContextMoveToPoint
-
CGPathAddLineToPoint, which replaces
CGContextAddLineToPoint
-
CGPathAddCurveToPoint, which replaces
CGContextAddCurveToPoint
-
CGPathAddEllipseInRect, which replaces
CGContextAddEllipseInRect
-
CGPathAddArc, which replaces
CGContextAddArc
-
CGPathAddRect, which replaces
CGContextAddRect
-
CGPathCloseSubpath, which replaces
CGContextClosePath
当你将Path创建好之后,你要选择stroke、fill
先说Stroke,就是勾画出创建的Path
Table 3-1 Parameters that affect how Quartz strokes the current path
|
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
|
Table 3-4 Functions that stroke paths
|
Function
|
Description
|
|
CGContextStrokePath
|
Strokes the current path.
|
|
CGContextStrokeRect
|
Strokes the specified rectangle.
|
|
CGContextStrokeRectWithWidth
|
Strokes the specified rectangle, using the specified line width.
|
|
CGContextStrokeEllipseInRect
|
Strokes an ellipse that fits inside the specified rectangle.
|
|
CGContextStrokeLineSegments
|
Strokes a sequence of lines.
|
|
CGContextDrawPath
|
If you pass the constant
kCGPathStroke, strokes the current path.
|
接下来看看
Fill,就是根据你的Path来进行填充,填充的区域是从创建的Path中,Quartz会当做每一个subpath都是闭合的。如果有多个闭合的,那么会有以下策略来选择:
![eosampleone.gif]()
Table 3-5 Functions that fill paths
|
Function
|
Description
|
|
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.
|
接下来就是设置blend mode的效果:
blend mode :CGContextSetBlendMode
指定Quartz 怎么在背景之上描绘
有很多不同的效果,但都是常量
Ex:
kCGBlendModeMultiply
效果:
![blm_multiply.gif]()
kCGBlendModeScreen
kCGBlendModeOverlay
…
最后来说说裁剪Path
Table 3-6 Functions that clip the graphics context
|
Function
|
Description
|
|
CGContextClip
|
Uses the nonzero winding number rule to calculate the intersection of the current path with the current clipping path.
|
|
CGContextEOClip
|
Uses the even-odd rule to calculate the intersection of the current path with the current clipping path.
|
|
CGContextClipToRect
|
Sets the clipping area to the area that intersects both the current clipping path and the specified rectangle.
|
|
CGContextClipToRects
|
Sets the clipping area to the area that intersects both the current clipping path and region within the specified rectangles.
|
|
CGContextClipToMask
|
Maps a mask into the specified rectangle and intersects it with the current clipping area of the graphics context. Any subsequent path drawing you perform to the graphics context is clipped.
|
如果你裁剪了Context,那么只有在裁剪区域内才会被描绘,才可见的,以外的不会被描绘,也不可见
4.Color&ColorSpace
不同的设备都有自己的颜色处理阈
Table 4-1 Color values in different color spaces
|
Values
|
Color space
|
Components
|
|
240 degrees, 100%, 100%
|
HSB
|
Hue, saturation, brightness
|
|
0, 0, 1
|
RGB
|
Red, green, blue
|
|
1, 1, 0, 0
|
CMYK
|
Cyan, magenta, yellow, black
|
|
1, 0, 0
|
BGR
|
Blue, green, red
|
Alpha
顾名思义,就是跟透明度有关系的
Quartz使用:CGContextSetAlpha函数来设置Context的透明度
![set_alpha.gif]()
iOS 不支持与设备无关的Color Space,iOS 应用只能使用Device Color Space
Table 4-2 Color-setting functions
|
Function
|
Use to set color for
|
|
CGContextSetRGBStrokeColor
CGContextSetRGBFillColor
|
Device RGB. At PDF-generation time, Quartz writes the colors as if they were in the corresponding generic color space.
|
|
CGContextSetCMYKStrokeColor
CGContextSetCMYKFillColor
|
Device CMYK. (Remains device CMYK at PDF-generation time.)
|
|
CGContextSetGrayStrokeColor
CGContextSetGrayFillColor
|
Device Gray. At PDF-generation time, Quartz writes the colors as if they were in the corresponding generic color space.
|
|
CGContextSetStrokeColorWithColor
CGContextSetFillColorWithColor
|
Any color space; you supply a CGColor object that specifies the color space. Use these functions for colors you need repeatedly.
|
|
CGContextSetStrokeColor
CGContextSetFillColor
|
The current color space. Not recommended. Instead, set color using a CGColor object and the functions
CGContextSetStrokeColorWithColor and
CGContextSetFillColorWithColor.
|
设置Rendering intent:CGContextSetRenderingIntent
其实就是指定不同空间的颜色值的映射关系
kCGRenderingIntentDefault
kCGRenderingIntentAbsoluteColorimetric
kCGRenderingIntentRelativeColorimetric
kCGRenderingIntentPerceptual
kCGRenderingIntentSaturation
5.Transforms
Quartz 2D定义了两个完全分离的坐标系:
User Space ,展现文档页
Device Space,展现设备分辨率
当你需要打印或者是展示文档的时候,Quartz会将坐标系从user Space 映射到Device Space
先说说transform,但是要知道本质就是,每一次的变换,其实在改变CTM
![spaces.gif]()
具体操作的函数:
//
static inline double radians (double degrees) {return degrees * M_PI/180;}
|
CGContextTranslateCTM (myContext, w/4, 0);
|
|
CGContextScaleCTM (myContext, .25, .5);
|
|
CGContextRotateCTM (myContext, radians ( 22.));
|
创建放射变换,
它是一种二维坐标到二维坐标之间的线性变换,保持二维图形的“平直性”和“平行性”
可以创建一个放射变换矩阵然后使用CGContextConcatCTM将矩阵应用到CTM
Table 5-1 Affine transform functions for translation, rotation, and scaling
|
Function
|
Use
|
|
CGAffineTransformMakeTranslation
|
To construct a new translation matrix from x and y values that specify how much to move the origin.
|
|
CGAffineTransformTranslate
|
To apply a translation operation to an existing affine transform.
|
|
CGAffineTransformMakeRotation
|
To construct a new rotation matrix from a value that specifies in radians how much to rotate the coordinate system.
|
|
CGAffineTransformRotate
|
To apply a rotation operation to an existing affine transform.
|
|
CGAffineTransformMakeScale
|
To construct a new scaling matrix from x and y values that specify how much to stretch or shrink coordinates.
|
|
CGAffineTransformScale
|
To apply a scaling operation to an existing affine transform.
|
空间转换:CGContextGetUserSpaceToDeviceSpaceTransform系列函数可以实现
数学原理:
在有限维的情况,每个仿射变换可以由一个矩阵A和一个向量b给出,它可以写作A和一个附加的列b。一个仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的矩阵乘法,只要加入一个额外的行到矩阵的底下,这一行全部是0除了最右边是一个1,而列向量的底下要加上一个1
6.Pattern
顾名思义,就是模板,一个patter就是一些连续的描绘操作在Context中重复的结果
如果使用pattern进行描绘,Quartz会将page分成很多cell,然后一个个通过回调方法来描绘
Figure 6-1 A pattern drawn to a window
![patterned_window.gif]()
使用Pattern就像使用Color对象一样,创建之后,设置好就可以了
Pattern有Colored和stenciled
Figure 6-8 A colored pattern has inherent color
![tartan.gif]()
Figure 6-9 A stencil pattern does not have inherent color
![star_patterns.gif]()
当你stroke或者是fill一个pattern时,Quartz
按照下面的步骤进行
-
Saves the graphics state.
-
Translates the current transformation matrix to the origin of the pattern cell.
-
Concatenates the CTM with the pattern matrix.
-
Clips to the bounding rectangle of the pattern cell.
-
Calls your drawing callback to draw the pattern cell.
-
Restores the graphics state.
Painting Colored Patterns
Quartz 按照下面的步骤进行
-
Write a Callback Function That Draws a Colored Pattern Cell
-
Set Up the Colored Pattern Color Space
-
Set Up the Anatomy of the Colored Pattern
-
Specify the Colored Pattern as a Fill or Stroke Pattern
-
Draw With the Colored Pattern
7.Shadow
Shadows have three characteristics:
-
An x-offset
-
A y-offset
-
A blur value, 指定图像是否有实边或者是虚边
Figure 7-1 A shadow
![angle.gif]()
Figure 7-2 A shadow with no blur and another with a soft edge
![blur_value.gif]()
Shadow是offset是坐标系相关的,不同的坐标系,就会有不同的位置
Follow these steps to paint with shadows:
-
Save the graphics state.
-
Call the function
CGContextSetShadow, passing the appropriate values.
-
Perform all the drawing to which you want to apply shadows.
-
Restore the graphics state.
Follow these steps to paint with colored shadows:
-
Save the graphics state.
-
Create a CGColorSpace object to ensure that Quartz interprets the shadow color values correctly.
-
Create a CGColor object that specifies the shadow color you want to use.
-
Call the function
CGContextSetShadowWithColor, passing the appropriate values.
-
Perform all the drawing to which you want to apply shadows.
-
Restore the graphics state.
8.Gradients
Quartz使用CGShadingRef
and CGGradientRef两个不透明的数据类型来创建渐变对象
Figure 8-1 An axial gradient along a 45 degree axis
![two_color_gradient.jpg]()
Figure 8-2 An axial gradient created with seven locations and colors
![rainbow_gradient.jpg]()
Figure 8-3 A radial gradient that varies between two circles
![cylinder6.gif]()
Figure 8-4 A radial gradient created by varying only the alpha component
![alpha_only.jpg]()
Figure 8-5 A radial gradient that varies between a point and a circle
![shaded_sphere.gif]()
Figure 8-6 Nested radial gradients
![torus.gif]()
Table 8-1 Differences between CGShading and CGGradient objects
|
CGGradient
|
CGShading
|
|
Can use the same object to draw axial and radial gradients.
|
Need to create separate objects for axial and radial gradients.
|
|
Set the geometry of the gradient at drawing time.
|
Set the geometry of the gradient at object creation time.
|
|
Quartz calculates the colors for each point in the gradient.
|
You must supply a callback function that calculates the colors for each point in the gradient.
|
|
Easy to define more than two locations and colors.
|
Need to design your callback to use more than two locations and colors, so it takes a bit more work on your part.
|
颜色扩展的效果
Figure 8-7 Extending an axial gradient
![extend_axial2.gif]()
Figure 8-8 Extending a radial gradient
![extend_radial.gif]()
使用CGGradient的步骤:
-
Create a CGGradient object, supplying a color space, an array of two or more color components, an array of two or more locations, and the number of items in each of the two arrays.
-
Paint the gradient by calling either
CGContextDrawLinearGradient or
CGContextDrawRadialGradient and supplying a context, a CGGradient object, drawing options, and the stating and ending geometry (points for axial gradients or circle centers and radii for radial gradients).
-
Release the CGGradient object when you no longer need it.
Listing 8-1 Creating a CGGradient object
|
CGGradientRef myGradient;
|
|
CGColorSpaceRef myColorspace;
|
|
size_t num_locations = 2;
|
|
CGFloat locations[2] = { 0.0, 1.0 };
|
|
CGFloat components[8] = { 1.0, 0.5, 0.4, 1.0, // Start color
|
|
0.8, 0.8, 0.3, 1.0 }; // End color
|
|
|
|
myColorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
|
myGradient = CGGradientCreateWithColorComponents (myColorspace, components,
|
|
locations, num_locations);
|
Listing 8-2 Painting an axial gradient using a CGGradient object
|
CGPoint myStartPoint, myEndPoint;
|
|
myStartPoint.x = 0.0;
|
|
myStartPoint.y = 0.0;
|
|
myEndPoint.x = 1.0;
|
|
myEndPoint.y = 1.0;
|
|
CGContextDrawLinearGradient (myContext, myGradient, myStartPoint, myEndPoint, 0);
|
Listing 8-3 Painting a radial gradient using a CGGradient object
|
CGPoint myStartPoint, myEndPoint;
|
|
CGFloat myStartRadius, myEndRadius;
|
|
myStartPoint.x = 0.15;
|
|
myStartPoint.y = 0.15;
|
|
myEndPoint.x = 0.5;
|
|
myEndPoint.y = 0.5;
|
|
myStartRadius = 0.1;
|
|
myEndRadius = 0.25;
|
|
CGContextDrawRadialGradient (myContext, myGradient, myStartPoint,
|
|
myStartRadius, myEndPoint, myEndRadius,
|
|
kCGGradientDrawsAfterEndLocation);
|
使用CGShading object:
CGShadingCreateAxial or
CGShadingCreateRadial
To paint the axial gradient shown in the figure, follow the steps explained in these sections:
-
Set Up a CGFunction Object to Compute Color Values
-
Create a CGShading Object for an Axial Gradient
-
Clip the Context
-
Paint the Axial Gradient Using a CGShading Object
-
Release Objects
To paint a radial gradient, follow the steps explained in the following sections:
-
Set Up a CGFunction Object to Compute Color Values.
-
Create a CGShading Object for a Radial Gradient
-
Paint a Radial Gradient Using a CGShading Object
-
Release Objects
9.Transparency Layers
transparent Layer是由两个以上的对象组合成的复合图像,
Ex:
Figure 9-1 Three circles as a composite in a transparency layer
![trans_layer1.gif]()
Figure 9-2 Three circles painted as separate entities
![trans_layer2.gif]()
描绘一个透明层需要以下三步骤:
-
Call the function
CGContextBeginTransparencyLayer.
-
Draw the items you want to composite in the transparency layer.
-
Call the function
CGContextEndTransparencyLayer.
10.Data Management in Quartz 2D
Quartz recognizes three broad categories of data sources and destinations:
-
URL. Data whose location can be specified as a URL can act as a supplier or receiver of data. You pass a URL to a Quartz function using the Core Foundation data type
CFURLRef.
-
CFData. The Core Foundation data types
CFDataRef and
CFMutableDataRef are data objects that let simple allocated buffers take on the behavior of Core Foundation objects.
-
Raw data. You can provide a pointer to data of any type along with a set of callbacks that take care of basic memory management for the data.
Table 10-1 Functions that move data into Quartz 2D
|
Function
|
Use this function
|
|
CGImageSourceCreateWithDataProvider
|
To create an image source from a data provider.
|
|
CGImageSourceCreateWithData
|
To create an image source from a CFData object.
|
|
CGImageSourceCreateWithURL
|
To create an image source from a URL that specifies the location of image data.
|
|
CGPDFDocumentCreateWithURL
|
To create a PDF document from data that resides at the specified URL.
|
|
CGDataProviderCreateSequential
|
To read image or PDF data in a stream. You supply callbacks to handle the data.
|
|
CGDataProviderCreateDirectAccess
|
To read image or PDF data in a block. You supply callbacks to handle the data.
|
|
CGDataProviderCreateWithData
|
To read a buffer of image or PDF data supplied by your application. You provide a callback to release the memory you allocated for the data.
|
|
CGDataProviderCreateWithURL
|
Whenever you can supply a URL that specifies the target for data access to image or PDF data.
|
|
CGDataProviderCreateWithCFData
|
To read image or PDF data from a CFData object.
|
Table 10-2 Functions that move data out of Quartz 2D
|
Function
|
Use this function
|
|
CGImageDestinationCreateWithDataConsumer
|
To write image data to a data consumer.
|
|
CGImageDestinationCreateWithData
|
To write image data to a CFData object.
|
|
CGImageDestinationCreateWithURL
|
Whenever you can supply a URL that specifies where to write the image data.
|
|
CGPDFContextCreateWithURL
|
Whenever you can supply a URL that specifies where to write PDF data.
|
|
CGDataConsumerCreateWithURL
|
Whenever you can supply a URL that specifies where to write the image or PDF data.
|
|
CGDataConsumerCreateWithCFData
|
To write image or PDF data to a CFData object.
|
|
CGDataConsumerCreate
|
To write image or PDF data using callbacks you supply.
|
11.Bitmap Images and Image Masks
不管是Bitmap images或者是Image mask都是使用CGImageRef类型表示
记住:bitmap Image 是一个具体分辨率位的数组
Keep in mind that a bitmap image is an array of bits at a specific resolution
CGImageMaskCreate方法用来创建Quartz image mask
Quartz uses the following information when it creates a bitmap image (CGImageRef):
-
A bitmap data source, which can be a Quartz data provider or a Quartz image source.
-
An optional decode array
-
An interpolation setting, which is a Boolean value that specifies whether Quartz should apply an interpolation algorithm when resizing the image.
-
A rendering intent that specifies how to map colors that are located within the destination color space of a graphics context. This information is not needed for image masks.
-
The image dimensions.
-
The pixel format, which includes bits per component, bits per pixel, and bytes per row
-
For images, color spaces and bitmap layout information to describe the location of alpha and whether the bitmap uses floating-point values. Image masks don’t require this information.
-
Table 11-1 Functions for creating images
|
Function
|
Description
|
|
CGImageCreate
|
A flexible function for creating an image. You must specify all the bitmap information that is discussed in
Bitmap Image Information.
|
|
CGImageSourceCreateImageAtIndex
|
Creates an image from an image source. Image sources can contain more than one image. See
Data Management in Quartz 2D for information on creating an image source.
|
|
CGImageSourceCreateThumbnailAtIndex
|
Creates a thumbnail image of an image that is associated with an image source. See
Data Management in Quartz 2D for information on creating an image source.
|
|
CGBitmapContextCreateImage
|
Creates an image by copying the bits from a bitmap graphics context.
|
|
CGImageCreateWithImageInRect
|
Creates an image from the data contained within a sub-rectangle of an image.
|
|
CGImageCreateCopy
|
A utility function that creates a copy of an image.
|
|
CGImageCreateCopyWithColorSpace
|
A utility function that creates a copy of an image and replaces its color space.
|
Masking techniques can produce many interesting effects by controlling which parts of an image are painted. You can:
-
Apply an image mask to an image. You can also use an image as a mask to achieve an effect that’s opposite from applying an image mask.
-
Use color to mask parts of an image, which includes the technique referred to as chroma key masking.
-
Clip a graphics context to an image or image mask, which effectively masks an image (or any kind of drawing) when Quartz draws the content to the clipped context.
Figure 11-5 The original image
![two_tigers.gif]()
Masking an Image with an Image Mask
![image_create_w_mask.gif]()
Masking an Image with an Image
![image_mask_image.gif]()
Masking an Image with Color
![chroma_key.gif]()
Masking an Image by Clipping the Context
![mask_as_mask.gif]()
Using Blend Modes with Images
CGContextSetBlendMode
![Screen Shot 2016-01-03 at 17.42.01.png]()
以上都是对应一些常量,设置之后会有对应的效果
12.Core Graphics Layer Drawing
Layers are suited for the following:
-
High-quality offscreen rendering of drawing that you plan to reuse. For example, you might be building a scene and plan to reuse the same background. Draw the background scene to a layer and then draw the layer whenever you need it. One added benefit is that
you don’t need to know color space or device-dependent information to draw to a layer.
-
Repeated drawing. For example, you might want to create a pattern that consists of the same item drawn over and over. Draw the item to a layer and then repeatedly draw the layer, as shown in Figure 12-1. Any Quartz object that you draw repeatedly—including
CGPath, CGShading, and CGPDFPage objects—benefits from improved performance if you draw it to a CGLayer. Note that a layer is not just for onscreen drawing; you can use it for graphics contexts that aren’t screen-oriented, such as a PDF graphics context.
-
Buffering. Although you can use layers for this purpose, you shouldn’t need to because the Quartz Compositor makes buffering on your part unnecessary. If you must draw to a buffer, use a layer instead of a bitmap graphics context.
Drawing with a Layer
You need to perform the tasks described in the following section to draw using a CGLayer object:
-
Create a CGLayer Object Initialized with an Existing Graphics Context
-
Get a Graphics Context for the Layer
-
Draw to the CGLayer Graphics Context
-
Draw the Layer to the Destination Graphics Context
13.PDF
请参考:
developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html#//apple_ref/doc/uid/TP30001066-CH214-TPXREF101
14.PostScript Conversion
developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_ps_convert/dq_ps_convert.html#//apple_ref/doc/uid/TP30001066-CH215-TPXREF101
|