iOS Quartz2D 渐变图形 CGGradient CGShading

最近在学习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>
时间: 2024-11-24 02:21:02

iOS Quartz2D 渐变图形 CGGradient CGShading的相关文章

iOS Quartz2D 透明层 TransparencyLayer

最近在研究iOS Quartz2D图形绘制引擎----->透明层TransparencyLayer 透明层 通过组合两个或多个对象来生成一个组合图形, 组合图形被看成是单一对象, 当需要在一组对象上使用特效的时候, 透明层非常有用 透明层的工作方式 Quartz2D的透明层类似很多流行的图形应用中的层, 层是独立的实体, Quartz维护为每个上下文维护一个透明栈, 并且透明层可以嵌套的, 但由于层通常是栈的一部分, 所以我们不能单独操作它们, 通过调用CGContextBeginTranspa

[html5] 学习笔记-Canvas 绘制渐变图形与绘制变形图形

在 HTML5 中,使用 Canvas API 绘制图形的知识,可以对绘制图形进行处理,包含使用 Canvas API 绘制渐变图形,使用 Canvas API 的坐标轴变换处理功能绘制变形图形.其中,左上方的点,为坐标轴原点(0,0). 1.绘制渐变图形 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <script> 6 function draw(id){ 7 va

关东升的《iOS实战:图形图像、动画和多媒体卷(Swift版)》上市了

承蒙广大读者的厚爱我的<iOS实战:图形图像.动画和多媒体卷(Swift版)>京东上市了,欢迎广大读者提出宝贵意见..http://item.jd.com/11760249.html 欢迎关注关东升新浪微博@tony_关东升. 关注智捷课堂微信公共平台,了解最新技术文章.图书.教程信息 更多精品iOS.Cocos.移动设计课程请关注智捷课堂官方网站:http://www.zhijieketang.com智捷课堂论坛网站:http://51work6.com/forum.php

Canvas3——绘制渐变图形与绘制变形图形

1.Canvas绘制渐变图形 (1)绘制线性渐变 createLinearGradient() **CanvasRenderingContext2D**.createLinearGradient()方法创建一个沿参数坐标指定的直线的渐变.该方法返回一个线性 CanvasGradient对象. CanvasGradient _ctx_.createLinearGradient(x0, y0, x1, y1); 参数 x0 起点的 x 轴坐标. y0 起点的 y 轴坐标. x1 终点的 x 轴坐标.

iOS边练边学--(Quartz2D)基本图形的绘制#附加自定义进度控件的练习

一.Quartz2D使用须知 Quartz2D的API是纯C语言的 Quartz2D的API来自于Core Graphics框架 二.<1>通过原始的方法(C语言)绘制简单图形--了解 <2>OC也封装了绘制图形的框架UIKit(贝瑟尔路径)--掌握 三.自定义进度控件的练习,效果图

iOS Quartz2D画基本图形

1.线 // 1.获得图形上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 设置线宽 CGContextSetLineWidth(ctx, 5); // 设置颜色 CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1); // 设置头尾部样式 CGContextSetLineCap(ctx, kCGLineCapRound); // 设置转折点的样式 CGContextSetLineJoin(ctx,

【iOS】Quartz2D基本图形

一.画线段 1 - (void)drawRect:(CGRect)rect 2 { 3 // Drawing code 4 // 1.获得图形上下文 5 CGContextRef ctx = UIGraphicsGetCurrentContext(); 6 7 // 2.拼接图形(路径) 8 // 设置线段宽度 9 CGContextSetLineWidth(ctx, 10); 10 11 // 设置线段头尾部的样式 12 CGContextSetLineCap(ctx, kCGLineCapR

Quartz2D--iOS下的图形绘制

一.基本介绍 Quartz 2D是一个二维绘图引擎,Quartz 2D的API是C语言,来自CoreGraphics框架,没有面向对象的思想. 1.作用:绘制图形:线条.三角形.矩形.圆.弧等 绘制文字 绘制.生成图片(图形) 读取.生成PDF 截图.裁剪图片 自定义UI控件 2.图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:1.保存绘图信息.绘图状态 2.决定绘制的输出目标(绘制到什么地方,输出目标可以是PDF文件.Bitmap或者

Quartz2D常见图形的绘制:线条、多边形、圆

UI高级 Quartz2D http://ios.itcast.cn  iOS学院 掌握 drawRect:方法的使用 常见图形的绘制:线条.多边形.圆 绘图状态的设置:文字颜色.线宽等 图形上下文状态的保存与恢复(图形上下文栈) 图片裁剪 截图 什么是Quartz2D Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作 Ø绘制图形 : 线条\三角形\矩形\圆\弧等 Ø绘制文字 Ø绘制\生成图片(图像) Ø读取\生成PDF Ø截图\裁剪图片 Ø自定义