CGContextDrawAngleGradient?

Plunging my feet into yet another graphic core pattern, I try to recreate the evil metal pen, and I landed on what is probably the problem of stopping the show.

There seems to be no way to draw Angle gradients in Core Graphics. I see CGContextDrawRadialGradient() and CGContextDrawLinearGradient() , but I see nothing that would allow me to draw an angle gradient. Does anyone know of a workaround or some kind of wireframe hidden somewhere to accomplish this without first rendering the handle to an image file?

AngleGradientKnob http://dl.dropbox.com/u/3009808/AngleGradient.png .

+8
cocoa-touch core-graphics gradient quartz-graphics
Aug 01 2018-11-18T00:
source share
2 answers

This is thrown away together, but it is an approach that I will probably take. This creates an angle gradient by drawing it directly into a bitmap using a simple trigger, and then cropping it in a circle. I create a memory grid using the grayscale color space, calculate the angle from the given point to the center, and then the color based on the periodic function, between 0 and 255. Of course, you could expand this to RGBA color.

Of course, you have to cache this and play with math to get the colors you need. It currently runs from black to white, which doesn’t look as good as we would like.

XD317.png

 - (void)drawRect:(CGRect)rect { CGImageAlphaInfo alphaInfo = kCGImageAlphaNone; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); size_t components = CGColorSpaceGetNumberOfComponents( colorSpace ); size_t width = 100; size_t height = 100; size_t bitsPerComponent = 8; size_t bytesPerComponent = bitsPerComponent / 8; size_t bytesPerRow = width * bytesPerComponent * components; size_t dataLength = bytesPerRow * height; uint8_t data[dataLength]; CGContextRef imageCtx = CGBitmapContextCreate( &data, width, height, bitsPerComponent, bytesPerRow, colorSpace, alphaInfo ); NSUInteger offset = 0; for (NSUInteger y = 0; y < height; ++y) { for (NSUInteger x = 0; x < bytesPerRow; x += components) { CGFloat opposite = y - height/2.; CGFloat adjacent = x - width/2.; if (adjacent == 0) adjacent = 0.001; CGFloat angle = atan(opposite/adjacent); data[offset] = abs((cos(angle * 2) * 255)); offset += components * bytesPerComponent; } } CGImageRef image = CGBitmapContextCreateImage(imageCtx); CGContextRelease(imageCtx); CGColorSpaceRelease(colorSpace); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGRect buttonRect = CGRectMake(100, 100, width, width); CGContextAddEllipseInRect(ctx, buttonRect); CGContextClip(ctx); CGContextDrawImage(ctx, buttonRect, image); CGImageRelease(image); } 
+11
Aug 02 2018-11-11T00:
source share

To expand on what is in the comments on the accepted answer, here is the code for generating an angle gradient using Core Image. This should work on iOS 8 or later.

 // generate a dummy image of the required size UIGraphicsBeginImageContextWithOptions(CGSizeMake(256.0, 256.0), NO, [[UIScreen mainScreen] scale]); CIImage *dummyImage = [CIImage imageWithCGImage:UIGraphicsGetImageFromCurrentImageContext().CGImage]; // define the kernel algorithm NSString *kernelString = @"kernel vec4 circularGradientKernel(__color startColor, __color endColor, vec2 center, float radius) { \n" " vec2 point = destCoord() - center;" " float rsq = point.x * point.x + point.y * point.y;" " float theta = mod(atan(point.y, point.x), radians(360.0));" " return (rsq < radius*radius) ? mix(startColor, endColor, 0.5+0.5*cos(4.0*theta)) : vec4(0.0, 0.0, 0.0, 1.0);" "}"; // initialize a Core Image context and the filter kernel CIContext *context = [CIContext contextWithOptions:nil]; CIColorKernel *kernel = [CIColorKernel kernelWithString:kernelString]; // argument array, corresponding to the first line of the kernel string NSArray *args = @[ [CIColor colorWithRed:0.5 green:0.5 blue:0.5], [CIColor colorWithRed:1.0 green:1.0 blue:1.0], [CIVector vectorWithCGPoint:CGPointMake(CGRectGetMidX(dummyImage.extent),CGRectGetMidY(dummyImage.extent))], [NSNumber numberWithFloat:200.0]]; // apply the kernel to our dummy image, and convert the result to a UIImage CIImage *ciOutputImage = [kernel applyWithExtent:dummyImage.extent arguments:args]; CGImageRef cgOutput = [context createCGImage:ciOutputImage fromRect:ciOutputImage.extent]; UIImage *gradientImage = [UIImage imageWithCGImage:cgOutput]; CGImageRelease(cgOutput); 

This creates the following image:

Angle gradient created using the main image

+3
Nov 30 '15 at 5:15
source share



All Articles