標籤:
最近在學習iOS Quartz2D二維圖形繪製--->漸層效果
Quartz2D 漸層
Quartz提供了兩個不透明資料odgago建立漸層: CGShadingRef 和 CGGradientRef
可以使用任何一種來建立軸向(axial)或徑向(radial)漸層.一個漸層是從一個顏色到另一個顏色的填充
一個軸向漸層(也成為線性漸層)
不說廢話直接上乾貨, 代碼和注釋還算全,不懂的自行百度吧
<span style="font-size:18px;">// Quartz2DViewThree.m// Quartz2DDemoOne//// Created by 帝炎魔 on 16/5/22.// Copyright © 2016年 帝炎魔. All rights reserved.//#import "Quartz2DViewThree.h"@implementation Quartz2DViewThree// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect { // Drawing code [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); /** * Quartz2D 漸層 Quartz提供了兩個不透明資料odgago建立漸層: CGShadingRef 和 CGGradientRef 可以使用任何一種來建立軸向(axial)或徑向(radial)漸層.一個漸層是從一個顏色到另一個顏色的填充 一個軸向漸層(也成為線性漸層) */ // [self myGradientWithstartPoint:CGPointMake(self.bounds.size.width, 0) endPoint:CGPointMake(0, self.bounds.size.height)]; // gradientColor(context, self.bounds); myPaintRadialShading(context, self.bounds); }#pragma mark ----- CGGradientCreateWithColorComponents 建立漸層圖層- (void)myGradientWithstartPoint:(CGPoint )startPoint endPoint:(CGPoint )endPoint{ CGContextRef context = UIGraphicsGetCurrentContext(); CGPoint myStartPoint, myEndPoint; myStartPoint.x = startPoint.x; myStartPoint.y = startPoint.y; myEndPoint.x = endPoint.x; myEndPoint.y = endPoint.y; CGGradientRef myGradient; CGColorSpaceRef mycolorSpace; size_t num_locations = 4; CGFloat locations[4] = {0.0, 0.33, 0.66, 1.0}; // 設定4個點 CGFloat components[16] = {0.1, 1.0, 0.2, 1.0, // RGB alpha 1.0, 0.1, 0.1, 1.0, 0.1, 0.1, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; mycolorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); /** * CGGradient * * @param mycolorSpace 設定色彩空間 色調 * @param components 設定關鍵點顏色的數組 * @param locations 設定關鍵點的位置和個數 * @param num_locations 設定點的個數 * * @return CGGradient */ myGradient = CGGradientCreateWithColorComponents(mycolorSpace, components, locations, num_locations); // CGContextDrawRadialGradient(context, myGradient, myStartPoint, 300, myEndPoint, 300, kCGGradientDrawsBeforeStartLocation); CGContextDrawLinearGradient(context, myGradient, myStartPoint, myEndPoint, kCGGradientDrawsBeforeStartLocation); // 釋放色彩空間對象 CGColorSpaceRelease(mycolorSpace); }/** * 使用CGShading對象繪製一個放射狀漸層 * * 使用CGShading對象來產生如下的圖形 為了繪製一個放射狀漸層, 需要如下的步驟: 1. 設定CGFunction 對象來計算顏色值---->>> 要有一個方法去計算這個圖形的顏色function 2. 建立放射狀漸層的CGShading對象 ----->>>> 建立CGShading對象來繪製漸層圖形 3. 使用CGShading對象來繪製放射狀漸層 4, 釋放對象 -----> 別忘了釋放對象CGShading對象 */#pragma mark ---- 漸層的圓的效果---> CGShading 繪製放射狀漸層的案void myPaintRadialShading(CGContextRef myContext, CGRect bounds) { CGPoint startPoint, // 漸層的起始點座標 endPoint; // 漸層的終止的點座標 CGFloat startRadius, endRadius; CGAffineTransform myTransform; CGFloat width = bounds.size.width; CGFloat height = bounds.size.height; /** * 初始點的座標和終止點座標 都是系統的座標系標準 通過設定起始點和終止點的座標和半徑可以繪製各種圖形 通過設定顏色function 可以得到五顏六色的圖形 * * */ startPoint = CGPointMake(.4,.4); startRadius = 1.; endPoint = CGPointMake(.5,.5); endRadius = .01; // CMYK的模式的狀態下 顏色會偏暗一點 CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); // 建立一個一個CGFunctionRef 的對象, 來計算顏色值 CGFunctionRef myShadingFunction = myGetFunction(colorspace); // 建立一個CGShadingRef來繪製放射狀漸層 /** * CGShadingRef * * @param colorspace CGColorSpace對象 色彩空間 * @param startPoint 起始點座標 對於軸向的漸層, 有軸線的起始點和終止點, 對於放射狀漸層, 有起始圓和終止圓中心的座標 * @param startRadius 起始點圓的半徑--->用於定義漸層地區的圓的起始半徑 * @param endPoint 終止點座標 * @param endRadius 終止點圓的半徑----> 用於定義漸層地區的圓的終止半徑 * @param myShadingFunction CGFunction 用於計算顏色的函數 單獨計算的函數 * @param extendStart false ----> 是否延伸到初始點 * @param extendEnd false ---> 是否延伸到終止點 * * @return 返回的是一個CGShadingRef的對象 配置好漸層的色彩空間, 起始點, 起始點圓的半徑, 終止點, 終止點的圓半徑, 顏色的返回函數, 得到這個對象之後, 開始繪製漸層圖形 */ CGShadingRef shading = CGShadingCreateRadial(colorspace, startPoint, startRadius, endPoint, endRadius, myShadingFunction, false, false); // 取得圖形的變換的CTM 矩陣 myTransform = CGAffineTransformMakeScale(width, height); CGContextConcatCTM(myContext, myTransform); // 儲存圖形的狀態 context CGContextSaveGState(myContext); // 修剪Clip一個圖形 CGContextClipToRect(myContext, CGRectMake(0, 0, 1, 1)); // 設定填充的RGB顏色 CGContextSetRGBFillColor(myContext, 1, 1, 1, 1); // 設定一個填充的圖形的frame CGContextFillRect(myContext, CGRectMake(0, 0, 1, 1)); // 繪製Shading CGContextDrawShading(myContext, shading); // 注意 :別忘了 釋放 色彩空間colorSpace , shading中間繪製對象, 計算顏色的方法CGFunction CGColorSpaceRelease(colorspace); // 釋放 CGShading的對象 CGShadingRelease(shading); // 釋放計算顏色值得函數對象 CGFunctionRelease(myShadingFunction); // 恢複狀態 restore context CGContextRestoreGState(myContext);}/** * 設定CGFunction 對象來計算顏色值 * * 計算放射狀漸層和軸向漸層顏色值函數並沒有什麼區別, 我們可以按照上面的軸向的設定CGFunction對象來計算顏色值, 函數遵循相同的原型, 每個函數擷取一個輸入值並計算N個值, 即色彩空間的每個顏色組件加一個alpha值 寫完顏色計算函數後調用它, 需要建立一個CGFunction對象, 如在軸向中設定CGFunction對象來計算顏色值 */static void myCalculateShadingValues(void *info, const CGFloat *in, CGFloat *out) { size_t k, components; /** * double值數組 控制顏色 對組中對應的R,G,B,alpha等值 */ double frequency[4] = {220, 220, 220, 0}; components = (size_t)info; for(k = 0; k < components - 1; k++) // 通過一個sin函數給色彩空間一個RGB的值 *out++ = (1 + sin(*in * frequency[k])) / 2; *out = 1;}/** * myGetFunction 建立myFunction 給Shading一個顏色回呼函數 * * */static CGFunctionRef myGetFunction(CGColorSpaceRef colorspace) { // 建立一個CGFloat數組, value的值 static const CGFloat input_value_range[2] = {0, 1}; static const CGFloat output_value_ranges[8] = {0, 1, 0, 1, 0, 1, 0, 1}; static const CGFunctionCallbacks callbacks = {0, &myCalculateShadingValues, NULL}; size_t numComponents = 1 + CGColorSpaceGetNumberOfComponents(colorspace); /** * CGFunctionCreate函數 * 1. 指向回調所需要的資料的指標, 2. 回調的輸入值的個數, Quartz要求回調攜帶一個輸入值 */ // 返回一個建立CGFunctionCreate CGFunction的方法 return CGFunctionCreate((void *)numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks);}#pragma mark --- CGShading 軸向的漸層的效果void gradientColor (CGContextRef myContext, CGRect bounds){ 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); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CGFunctionRef myShadingFunction = myGetGradientFunction(colorspace); CGShadingRef shading = CGShadingCreateAxial(colorspace, startPoint, endPoint, myShadingFunction, 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); CGContextAddArc(myContext, .5, .5, .3, 0, M_PI, 0); CGContextClosePath(myContext); CGContextClip(myContext); CGContextDrawShading(myContext, shading); CGColorSpaceRelease(colorspace); CGShadingRelease(shading); CGFunctionRelease(myShadingFunction); CGContextRestoreGState(myContext); }static CGFunctionRef myGetGradientFunction (CGColorSpaceRef colorspace) { static const CGFloat input_value_range[2] = {0, 1}; static const CGFloat output_value_ranges[8] = {0, 1, 0, 1, 0, 1, 0, 1}; static const CGFunctionCallbacks callbacks = {0, &myGradientCalculateShadingValues, NULL}; size_t numComponents = 1 + CGColorSpaceGetNumberOfComponents (colorspace); return CGFunctionCreate((void *)numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks);}static void myGradientCalculateShadingValues(void *info, const CGFloat *in, CGFloat *out) { CGFloat v; size_t k, components; static const CGFloat c[] = {1, 0, .5, 0}; components = (size_t)info; v = *in; for(k = 0; k < components -1; k++) *out++ = c[k] * v; *out = 1;}@end</span>
iOS Quartz2D 漸層圖形 CGGradient CGShading