tags:

views:

197

answers:

2

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?

A: 

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.

gavinb
+3  A: 

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.
  • Note that locations values should be between 0.0 and 1.0. You need to calibrate your color values depending on the radius.
Mo