Reputation: 2783
I have an array of CGPoints, and I'd like to fill the whole screen with colours, the colour of each pixel depending on the total distance to each of the points in the array. The natural way to do this is to, for each pixel, compute the total distance, and turn that into a colour. Questions follow:
1) How can I colour a single pixel in Quartz? I've been thinking of making 1 by 1 rectangles.
2) Are there better, more efficient ways to achieve this effect?
Upvotes: 1
Views: 2337
Reputation: 7255
You don't need to draw it pixel by pixel. You can use radial gradients:
CGPoint points[count];
/* set the points */
CGContextSaveGState(context);
CGContextBeginTransparencyLayer(context, NULL);
CGContextSetAlpha(context, 0.5);
CGContextSetBlendMode(context, kCGBlendModeXOR);
CGContextClipToRect(context, myFrame);
CGFloat radius = myFrame.size.height+myFrame.size.width;
CGColorSpaceRef colorSpace;
CFArrayRef colors;
const CGFloat * locations;
/* create the colors for the gradient */
for(NSUInteger i = 0;i<count;i++){
CGGradientRef gradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceGray(), colors, locations);
CGContextDrawRadialGradient(context, gradient, points[i], 0.0, points[i], radius, 0);
}
CGContextSetAlpha(context, 1.0);
CGContextEndTransparencyLayer(context);
CGContextRestoreGState(context);
Most of the code is clear, but here are some points:
kCGBlendMode
basically adds the value of back- and foreground if both have the same alpha and alpha is not 1.0. You might also be able to use kCGBlendModeColorBurn
without the need to play with transparency. Check the reference.radius
is big enough to cover the whole frame. You can set a different value.locations
values should be between 0.0 and 1.0. You need to calibrate your color values depending on the radius
.Upvotes: 4
Reputation: 20028
This has been asked before:
From Quartz, a 1x1 rectangle would do what you want. But it is certainly not very efficient.
You are better off creating a memory buffer, calculating your point distances, and writing into the array directly within your processing loop. Then to display the result, simply create a CGImage which you can then render into your screen context.
Upvotes: 0