使用CGShading显示和颜色数组

时间:2011-08-05 22:02:49

标签: iphone core-graphics

我需要在路径中显示一组CGColors。我尝试用CGGradient做这个,但我不希望颜色是值之间的混合。看起来最好的解决方案是使用GGShading对象,但我无法弄清楚它们是如何工作的。我主要想知道我需要为CGShading的CGFunction输入提供什么。

有人能指出我正确的方向,我需要使这个CGFunction看起来只是在指定的CGPath上显示一个数组去CGColors吗?

谢谢!

1 个答案:

答案 0 :(得分:5)

也许有点晚了,所以我希望这对你有用。我已经列出了一个简单的UIView子类的代码,它使用你描述的着色绘制一个圆圈。带注释的代码应该是不言自明的。

@implementation CGShadingCircle


// This is the callback of our shading function.
// info:    a pointer to our NSMutableArray of UIColor objects
// inData:  contains a single float that gives is the current position within the gradient
// outData: we fill this with the color to display at the given position
static void CGShadingCallback(void* info, const float* inData, float* outData) {
    // Our colors
    NSMutableArray* colors = (NSMutableArray*)info;
    // Position within the gradient, ranging from 0.0 to 1.0
    CGFloat position = *inData;

    // Find the color that we want to used based on the current position;
    NSUInteger colorIndex = position * [colors count];

    // Account for the edge case where position == 1.0
    if (colorIndex >= [colors count])
        colorIndex = [colors count] - 1;

    // Get our desired color from the array
    UIColor* color = [colors objectAtIndex:colorIndex];

    // Copy the 4 color components (red, green, blue, alpha) to outData
    memcpy(outData, CGColorGetComponents(color.CGColor), 4 * sizeof(CGFloat));  
}


// Set up our colors and shading function
- (void)initInternal {  
    _colors = [[NSMutableArray alloc] init];

    // Creating the colors in this way ensures that the underlying color space is UIDeviceRGBColorSpace
    // and thus has 4 color components: red, green, blue, alpha
    [_colors addObject:[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f]]; // Red
    [_colors addObject:[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:1.0f]]; // Green
    [_colors addObject:[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f]]; // Blue
    [_colors addObject:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f]]; // White
    [_colors addObject:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]]; // Black

    // Define the shading callbacks
    CGFunctionCallbacks callbacks;
    callbacks.version = 0;                      // Defaults to 0
    callbacks.evaluate = CGShadingCallback;     // This is our color selection function
    callbacks.releaseInfo = NULL;               // Not used

    // As input to our function we want 1 value in the range [0.0, 1.0].
    // This is our position within the 'gradient'.
    size_t domainDimension = 1;
    CGFloat domain[2] = {0.0f, 1.0f};

    // The output of our function is 4 values, each in the range [0.0, 1.0].
    // This is our selected color for the input position.
    // The 4 values are the red, green, blue and alpha components.
    size_t rangeDimension = 4;
    CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};

    // Create the shading function
    _shadingFunction = CGFunctionCreate(_colors, domainDimension, domain, rangeDimension, range, &callbacks);   
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initInternal];
    }
    return self;
}

- (id)initWithCoder:(NSCoder*)decoder {
    self = [super initWithCoder:decoder];
    if (self) {
        [self initInternal];
    }
    return self;
}

- (void)dealloc {
    [_colors release];
    CGFunctionRelease(_shadingFunction);

    [super dealloc];
}

- (void)drawRect:(CGRect)rect {
    CGRect b = self.bounds;
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // Create a simple elliptic path
    CGContextAddEllipseInRect(ctx, b);
    // Set the current path as the clipping path
    CGContextClip(ctx);

    // Create our shading using the function that was defined earlier.
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGShadingRef shading = CGShadingCreateAxial(colorspace,
        CGPointMake(CGRectGetMinX(b), CGRectGetMidY(b)),
        CGPointMake(CGRectGetMaxX(b), CGRectGetMidY(b)),
        _shadingFunction,
        true,
        true);

    // Draw the shading
    CGContextDrawShading(ctx, shading);


    // Cleanup
    CGShadingRelease(shading);
    CGColorSpaceRelease(colorspace);
}

@end

这给了我以下输出:

我希望这有帮助!