你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS Quartz2D 漸變圖形 CGGradient CGShading

iOS Quartz2D 漸變圖形 CGGradient CGShading

編輯:IOS開發綜合

最近在學習iOS Quartz2D二維圖形繪制--->漸變效果
Quartz2D 漸變
Quartz提供了兩個不透明數據odgago創建漸變: CGShadingRef 和 CGGradientRef
可以使用任何一種來創建軸向(axial)或徑向(radial)漸變.一個漸變是從一個顏色到另一個顏色的填充
一個軸向漸變(也成為線性漸變)
 

\\

\\

 

 

不說廢話直接上干貨, 代碼和注釋還算全,不懂的自行百度吧

 

<SPAN style="FONT-SIZE: 18px">//  Quartz2DViewThree.m
//  Quartz2DDemoOne

#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>


 

 
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved