# Quartz 2D编程指南之八：渐变

Quartz函数提供了一个丰富的功能来创建渐变效果。这一部分显示了一些我们能达到的效果。图8-1中的轴向渐变由橙色向黄色渐变。在这个例子中，渐变轴相对于原点倾斜了45度角。

Figure 8-1 An axial gradient along a 45 degree axis

Quartz也允许我们指定一系列的颜色和位置值，以沿着轴来创建更复杂的轴向渐变，如图8-2所示。起始点的颜色值是红色，结束点的颜色是紫罗兰色。同时，在轴上有五个位置，它们的颜色值分别被设置为橙、黄、绿、蓝和靛蓝。我们可以把它看成沿着同一轴线的六段连续的线性渐变。虽然这里的轴线与图8-1是一样的，但这不是必须的。轴线的角度由我们提供的两个端点定义。

Figure 8-2 An axial gradient created with seven locations and colors

Figure 8-4 A radial gradient created by varying only the alpha component

Figure 8-5 A radial gradient that varies between a point and a circle

Figure 8-7 Extending an axial gradient

Listing 8-1 Creating a CGGradient object

CGColorSpaceRef myColorspace;

size_tnum_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);

locations, num_locations);

CGPoint myStartPoint, myEndPoint;

myStartPoint.x =0.0;

myStartPoint.y =0.0;

myEndPoint.x =1.0;

myEndPoint.y =1.0;

CGPoint myStartPoint, myEndPoint;

myStartPoint.x =0.15;

myStartPoint.y =0.15;

myEndPoint.x =0.5;

myEndPoint.y =0.5;

Listing 8-4 The variables used to create a radial gradient by varying alpha

CGPoint myStartPoint, myEndPoint;

myStartPoint.x =0.2;

myStartPoint.y =0.5;

myEndPoint.x =0.65;

myEndPoint.y =0.5;

size_tnum_locations =2;

CGFloat locations[2] = {0,1.0};

CGFloat components[8] = {0.95,0.3,0.4,1.0,

0.95,0.3,0.4,0.1};

Listing 8-5 The variables used to create a gray gradient

size_tnum_locations =3;

CGFloat locations[3] = {0.0,0.5,1.0};

CGFloat components[12] = {1.0,1.0,1.0,1.0,

0.5,0.5,0.5,1.0,

1.0,1.0,1.0,1.0};

Figure 8-10 An axial gradient with three locations

CGColorSpace对象：颜色空间

Figure 8-11 An axial gradient that is clipped and painted

const CGFloat *in：Quartz传递in数组给回调。数组中的值必须在为CGFunction对象定义的输入值范围内。例如，输入范围是0到1；看代码清单8-7

CGFloat *out：我们的回调函数传递out数组给Quartz。它包含用于颜色空间中每个颜色组件的元素及一个alpha值。输出值应该在CGFunction对象中定义的输出值的范围内，例如，输出范围是0到1；看代码清单8-7。

Listing 8-6 Computing color component values

static void myCalculateShadingValues(void*info,const CGFloat *in,CGFloat *out){

CGFloat v;

size_tk, components;

staticconstCGFloat c[] = {1,0,.5,0};

components = (size_t)info;

v = *in;

for(k =0; k < components-1; k++)

*out++ = c[k] * v;

*out++ =1;

}

Listing 8-7 Creating a CGFunction object

static CGFunctionRefmyGetFunction(CGColorSpaceRef colorspace){

size_tnumComponents;

staticconstCGFloat input_value_range [2] = {0,1};

staticconstCGFloat output_value_ranges [8] = {0,1,0,1,0,1,0,1};

staticconstCGFunctionCallbacks callbacks = {0,

NULL};

numComponents =1+ CGColorSpaceGetNumberOfComponents (colorspace);

returnCGFunctionCreate ((void*) numComponents,

1,

input_value_range,

numComponents,

output_value_ranges,

&callbacks);

}

CGPoint    startPoint,

endPoint;

CGFunctionRef myFunctionObject;

startPoint = CGPointMake(0,0.5);

endPoint = CGPointMake(1,0.5);

colorspace = CGColorSpaceCreateDeviceRGB();

myFunctionObject = myGetFunction (colorspace);

startPoint, endPoint,

myFunctionObject,

false,false);

Listing 8-9 Adding a semicircle clip to the graphics context

CGContextBeginPath (myContext);

CGContextClosePath (myContext);

CGContextClip (myContext);

Listing 8-10 Releasing objects

CGColorSpaceRelease (colorspace);

CGFunctionRelease (myFunctionObject);

CGPoint    startPoint,

endPoint;

CGAffineTransform myTransform;

CGFloat width = bounds.size.width;

CGFloat height = bounds.size.height;

startPoint = CGPointMake(0,0.5);

endPoint = CGPointMake(1,0.5);

colorspace = CGColorSpaceCreateDeviceRGB();

startPoint, endPoint,

false,false);

myTransform = CGAffineTransformMakeScale (width, height);

CGContextConcatCTM (myContext, myTransform);

CGContextSaveGState (myContext);

CGContextClipToRect (myContext, CGRectMake(0,0,1,1));

CGContextSetRGBFillColor (myContext,1,1,1,1);

CGContextFillRect (myContext, CGRectMake(0,0,1,1));

CGContextBeginPath (myContext);

CGContextClosePath (myContext);

CGContextClip (myContext);

CGColorSpaceRelease (colorspace);

CGContextRestoreGState (myContext);

}

Listing 8-12 Computing color component values

constCGFloat *in,

CGFloat *out)

{

size_tk, components;

doublefrequency[4] = {55,220,110,0};

components = (size_t)info;

for(k =0; k < components -1; k++)

*out++ = (1+sin(*in * frequency[k]))/2;

*out++ =1;// alpha

}

CGPoint startPoint, endPoint;

startPoint = CGPointMake(0.25,0.3);

endPoint = CGPointMake(.7,0.7);

colorspace = CGColorSpaceCreateDeviceRGB();

startPoint,

endPoint,

false,

false);

Listing 8-10 Releasing objects

CGColorSpaceRelease (colorspace);

CGFunctionRelease (myFunctionObject);

{

CGPoint startPoint,

endPoint;

CGAffineTransform myTransform;

CGFloat width = bounds.size.width;

CGFloat height = bounds.size.height;

startPoint = CGPointMake(0.25,0.3);

endPoint = CGPointMake(.7,0.7);

colorspace = CGColorSpaceCreateDeviceRGB();

false,false);

myTransform = CGAffineTransformMakeScale (width, height);

CGContextConcatCTM (myContext, myTransform);

CGContextSaveGState (myContext);

CGContextClipToRect (myContext, CGRectMake(0,0,1,1));

CGContextSetRGBFillColor (myContext,1,1,1,1);

CGContextFillRect (myContext, CGRectMake(0,0,1,1));

CGColorSpaceRelease (colorspace);

CGContextRestoreGState (myContext);

}

### 推荐阅读更多精彩内容

权宜平和阅读 295评论 0 0
• Quartz2D 编程指南（一）概览、图形上下文、路径、颜色与颜色空间 Quartz2D 编程指南（二）变换、图案...
xuyafei86阅读 1,489评论 0 21
• 亲爱的姑娘，从今天起，你就真正26岁了，已经开始吃27岁的饭了，话说奔三也就是两三年的事了。 毕业四年的年的你虽本...
苏穆凉阅读 109评论 4 0
• 对自己 对世界 对存在 依然困惑 依然不知所措 依然在不停的寻找生命中那失落的一角 寻寻觅觅，兜兜转转 对于生命 ...
小飞侠303阅读 128评论 0 2
• 一下回到解放前。
擎天柱_6e9a阅读 39评论 0 0