Apply a transform in CGContextRef for drawInRect

cgaffinetransform, cgcontext, ios, quartz-graphics, uiimage

Solution

Seems like you just forgot to translate the origin of the context before and after the rotation. Here, try this:

- (UIImage*)addToImage:(UIImage *)baseImage newImage:(UIImage*)newImage atPoint:(CGPoint)point transform:(CGAffineTransform)transform {

    UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, [[UIScreen mainScreen] scale]);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGRect baseRect = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height);

    [baseImage drawInRect:baseRect];

    CGRect newRect = CGRectMake(point.x, point.y, newImage.size.width, newImage.size.height);

    CGContextTranslateCTM(context, point.x, point.y);
    CGContextConcatCTM(context, transform);
    CGContextTranslateCTM(context, -point.x, -point.y);

    [newImage drawInRect:newRect];

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

    return result;
}

EDIT:

If you want to rotate the image around its center, add the halves of the image's sides to the corresponding translation values:

float xTranslation = point.x+newRect.size.width/2;
float yTranslation = point.y+newRect.size.height/2;

CGContextTranslateCTM(context, xTranslation, yTranslation);
CGContextConcatCTM(context, transform);
CGContextTranslateCTM(context, -xTranslation, -yTranslation);

Problem

In the code below I'm adding a small image to a large image. I need to be able to apply a transform to the small image. Right now something weird is going on, for example if I pass in a transform of `CGAffineTransformMakeRotation(M_PI_2)`, the newImage is not rotated in place but rather drawn somewhere off screen. How can I fix this? ``` + (UIImage*)addToImage:(UIImage *)baseImage newImage:(UIImage*)newImage atPoint:(CGPoint)point transform:(CGAffineTransform)transform { UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 1); CGContextRef context = UIGraphicsGetCurrentContext(); [baseImage drawInRect:CGRectMake(0, 0, baseImage.size.width, baseImage.size.height)]; CGRect newRect = CGRectMake(point.x, point.y, newImage.size.width, newImage.size.height); CGContextConcatCTM(context, transform); [newImage drawInRect:newRect]; UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return result; } ``` Note that I only want to apply the transform to newImage, not baseImage.

Original source