Reputation: 11211
I'm trying to draw a simple grid pattern on a black background using Core Graphics. The gridlines will be green. I am currently creating and drawing in an image context, then using the resulting image to pattern the background of my view:
CGFloat gridSize = 45;
UIGraphicsBeginImageContext(CGSizeMake(gridSize, gridSize));
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(ctx);
// Create black background fill.
CGContextSetFillColorWithColor(ctx, [[UIColor colorWithRed:0.0
green:0.0
blue:0.0
alpha:1.0] CGColor]);
CGContextMoveToPoint(ctx, 0, 0);
CGContextAddLineToPoint(ctx, gridSize, 0);
CGContextAddLineToPoint(ctx, gridSize, gridSize);
CGContextAddLineToPoint(ctx, 0, gridSize);
CGContextAddLineToPoint(ctx, 0, 0);
CGContextFillPath(ctx);
// Set context variables for line drawing.
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
CGContextSetStrokeColorWithColor(ctx, [[UIColor colorWithRed:0.0
green:1.0
blue:0.0
alpha:1.0] CGColor]);
CGContextSetLineWidth(ctx, 1);
// Draw top and bottom grid lines.
CGContextMoveToPoint(ctx, 0, 0);
CGContextAddLineToPoint(ctx, gridSize, 0);
CGContextMoveToPoint(ctx, gridSize, gridSize);
CGContextAddLineToPoint(ctx, 0, gridSize);
CGContextStrokePath(ctx);
// Draw left and right grid lines.
CGContextMoveToPoint(ctx, gridSize, 0);
CGContextAddLineToPoint(ctx, gridSize, gridSize);
CGContextMoveToPoint(ctx, 0, gridSize);
CGContextAddLineToPoint(ctx, 0, 0);
CGContextStrokePath(ctx);
// Draw a "cross" in the center of the image to troubleshoot blending.
CGContextMoveToPoint(ctx, 20, 20);
CGContextAddLineToPoint(ctx, 40, 20);
CGContextStrokePath(ctx);
CGContextMoveToPoint(ctx, 30, 10);
CGContextAddLineToPoint(ctx, 30, 30);
CGContextStrokePath(ctx);
UIGraphicsPopContext();
UIImage *gridImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Set background color to a pattern based on the drawn image.
[self setBackgroundColor:[[UIColor alloc] initWithPatternImage:gridImage]];
However, this code results in the following:
Note that there are brighter areas that occur at the intersection of any lines. The crosses that are somewhat randomly placed within the grid pattern were put there just to test whether the bright areas still occur when not affected by the edges of the patterning (they do).
It is these bright areas at the line intersections that I wish to alleviate. To make sure I hadn't accidentally fooled myself using some sort of optical illusion, I checked the pixel colors in the middle of the lines as well as at their intersections.
Pixel values at midpoint of green line:
Pixel values at intersection of two green lines:
I have checked the Apple Core Graphics docs regarding blending modes, and ascertained that the default blending mode is kCGBlendModeNormal
, which should, when painting colors with alpha = 1
, should "completely obscure the background", and any previously painted colors. Though this is the default blending mode, I still set it explicitly in the above code, and yet I still see these bright squares.
What I expect instead is to see the lines of a uniform green color, presumably with the RGB profile:
What am I missing?
Upvotes: 1
Views: 448
Reputation: 78865
It looks as if the lines are drawn with an alpha of 50% but double the specified line width. This happens if you have a line width of 1 pixel but draw horizontal or vertical lines using integer coordinates.
Your coordinates specify an infinitely thin line from the start to the end coordinates. The drawn line should then extend to both sides of the thin line by half the stroke width. In your case, this means the line would need to cover half a pixel to the left and to the right or to the top and to the bottom of grid. Since only full pixels can be drawn, the alpha is reduced to 50% and the full pixel drawn instead.
The solution is simple: Add 0.5 to all your coordinates.
Upvotes: 1