2

I have a closed path defined as a CGPath (actually, CGMutablePath).

I want to color burn a specific region of a UIImage defined by the path. I've been fiddling around with Core Graphics, but currently my only options are to color tint a rectangular area defined by a CGRect, not a path.

Can anyone point me in the right direction?

--Update

Using the help of Rob I managed to rotate the image I got from the camera 90 deg to let it appear correctly in the UIImageview..

Only problem I have left is the PATH i need to draw is still 90 degrees of, and out of scale. The code i currently use is as following:

- (UIImage*)applyColorFillWithPath:(CGMutablePathRef) path withColor:(UIColor*)color {

CGFloat targetWidth = self.size.width;
CGFloat targetHeight = self.size.height;
CGImageRef imageRef = [self CGImage];
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

if (bitmapInfo == kCGImageAlphaNone) {
    bitmapInfo = kCGImageAlphaNoneSkipLast;
}

CGContextRef context;
if (self.imageOrientation == UIImageOrientationUp || self.imageOrientation == UIImageOrientationDown) {
    //UIGraphicsBeginImageContext(CGSizeMake(targetWidth, targetHeight));
    context = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

} else {
    //UIGraphicsBeginImageContext(CGSizeMake(targetHeight, targetWidth));
    context = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

}   

// set the fill color
//[color setFill];

if (self.imageOrientation == UIImageOrientationLeft) {
    CGContextRotateCTM(context, radians(90));
    CGContextTranslateCTM (context, 0, -targetHeight);

} else if (self.imageOrientation == UIImageOrientationRight) {
    CGContextRotateCTM (context, radians(-90));
    CGContextTranslateCTM (context, -targetWidth, 0);

} else if (self.imageOrientation == UIImageOrientationUp) {
    // NOTHING
} else if (self.imageOrientation == UIImageOrientationDown) {
    CGContextTranslateCTM (context, targetWidth, targetHeight);
    CGContextRotateCTM (context, radians(-180));
}

CGContextDrawImage(context, CGRectMake(0, 0, targetWidth, targetHeight),imageRef);

CGContextBeginPath(context);
CGContextAddPath(context, path);
CGContextSaveGState(context);
CGContextClip(context);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, CGPathGetBoundingBox(path));
CGContextRestoreGState(context);

// Turn the bitmap context into a UIImage.
CGImageRef cgImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *coloredImg = [UIImage imageWithCGImage:cgImage scale:1 orientation:UIImageOrientationUp];
CGImageRelease(cgImage);

//return the color-burned image
return coloredImg;
}

The following image is the result. De red rectangle is a representation of the CGPATH. The white square is actually the result of the above method on the path.

http://i41.tinypic.com/f1zbdi.png

I suppose I need to manually rotate the CGPATH 90 degrees using COS math's and what not.. Although I might oversee something.. ?

1 Answers1

2

Set the context's clipping path to your path to constrain the affected pixels.

CGContextRef gc = myGraphicsContext();
CGMutablePathRef path = myMutablePathRef();

CGContextBeginPath(gc);
CGContextAddPath(gc, path);
CGContextSaveGState(gc); {
    CGContextClip(gc);

    // Do color burn.  For example:
    CGContextSetBlendMode(gc, kCGBlendModeColorBurn);
    CGContextSetFillColorWithColor(gc, [UIColor redColor].CGColor);
    CGContextFillRect(gc, CGPathGetBoundingBox(path));
} CGContextRestoreGState(gc);
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Thanks Rob! You really helped me out here. Basically I was thinking it way too difficult.. Trying to create a mask, copying the contents out, coloring it and merging that back into the source picture... – Timon Van Rooijen Jan 21 '12 at 21:14
  • Only strange thing I have left is the fact that the imageview containing the image rotates the image by 90deg while applying the colorburn. Looks like it autorotates to landscape or something. The UIImage is a photo from the imagepicker taken in portrait mode. I have set the Imageview mode to "scale to fill". – Timon Van Rooijen Jan 22 '12 at 12:04
  • http://stackoverflow.com/questions/1260249/resizing-uiimages-pulled-from-the-camera-also-rotates-the-uiimage – rob mayoff Jan 22 '12 at 16:03
  • Thanks (again) Rob... I did searched for similar problems but I keep getting the CGPath drawn incorrectly, eg 90 degrees off.. I have re-stated my original question based on your input. – Timon Van Rooijen Jan 23 '12 at 11:11