Colourise CGContextRef But Preserve Alpha

1.1k views Asked by At

I have a CGContextRef and can draw on it and specify the alpha, and if I try and use it it works perfectly. However, I am trying to colourise it (currently either red or green), but whatever blend mode I choose, the alpha is set to 1 (because I am drawing with alpha as 1). Drawing it the correct colour is not really a viable option, as I would like to be able to colour UIImages loaded from the filesystem as well, so how should I achieve this?

Edit: Example code (width and height are predefined floats, points is an array of CGPoints all of which lie inside the context and color is a UIColor with an opacity of 100%) -

UIGraphicsBeginImageContext(CGSizeMake(width,height));

CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextClearRect(contextRef, CGRectMake(0.0f, 0.0f, width, height));
CGContextSetRGBStrokeColor(contextRef, 0.0f, 0.0f, 0.0f, 1.0f);
CGContextSetRGBFillColor(contextRef, 1.0f, 1.0f, 1.0f, 1.0f);
CGContextSetLineWidth(contextRef, lineWidth);

CGContextBeginPath(contextRef);
CGContextMoveToPoint(contextRef, points[0].x, points[0].y);
for (int i = 1; i < 4; i++) {
    CGContextAddLineToPoint(contextRef, points[i].x, points[i].y);
}
CGContextAddLineToPoint(contextRef, points[0].x, points[0].y); // Encloses shape

CGContextDrawPath(contextRef, kCGPathFillStroke);

[color setFill];

CGContextBeginPath(contextRef);
CGContextSetBlendMode(contextRef, kCGBlendModeMultiply);
CGContextAddRect(contextRef, CGRectMake(0.0f, 0.0f, width, height));
CGContextDrawPath(contextRef, kCGPathFill);

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Thank you in advance for your help,
jrtc27

1

There are 1 answers

0
jrtc27 On BEST ANSWER

The problem was I needed a CGContextClipToMask. This meant my code required the following:

CGContextTranslateCTM(contextRef, 0, height);
CGContextScaleCTM(contextRef, 1.0, -1.0);

to convert the coordinates and then

CGRect rect = CGRectMake(0.0f, 0.0f, width, height);
CGContextClipToMask(contextRef, rect, UIGraphicsGetImageFromCurrentImageContext().CGImage);

to fix it.