Smart Home Smart Home - 18 days ago 5
iOS Question

How to draw an UIImage using drawAtPoint after translating the image graphics context

I have an image of a clock hand. I am trying to created rotated versions of this image so that Ic an play it using animation (using

UIImageView's
animatedImages
approach).

In the code below, I am seeing that if I apply a CGContextTranslateCTM to the image graphics context, the image is not drawn unless I increase the size I give to the
UIGraphicsBeginImageContextWithOptions
to make it bigger than image size.

Why is this needed? I would think that all translation does is to move the definition of how the
drawAtPoint:
interprets where 0,0 is?

**Edited Code showing more details*

-(void) animatedClock
{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(20, 100), NO, 0);

UIBezierPath *clockHand = [[UIBezierPath alloc] init];
[[UIColor yellowColor] setFill];
[clockHand moveToPoint:CGPointMake(0, 20)];
[clockHand addLineToPoint:CGPointMake(10, 0)];
[clockHand addLineToPoint:CGPointMake(20, 20)];
[clockHand fill];

[clockHand removeAllPoints];
[clockHand moveToPoint:CGPointMake(5, 100)];
[clockHand addLineToPoint:CGPointMake(5, 20)];
[clockHand addLineToPoint:CGPointMake(15, 20)];
[clockHand addLineToPoint:CGPointMake(15, 100)];
[clockHand closePath];
[clockHand fill];


UIImage *baseImage = UIGraphicsGetImageFromCurrentImageContext();
NSLog(@"Image size is %@", NSStringFromCGSize(baseImage.size));
UIGraphicsEndImageContext();

//The screenshot will show baseimage, an arrow that is pointed upwards and at the top left of the screen
UIImageView *imageView = [[UIImageView alloc] initWithImage:baseImage];
UIGraphicsEndImageContext();
[self.view addSubview:imageView];

//This code is just to see where 100, 100 is on screen
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100, 5, 5)];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];

for (NSUInteger index = 0; index <= 8; index++)
{
//UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 0); //If I keep this line then nothing is shown
UIGraphicsBeginImageContextWithOptions(CGSizeMake(500, 600), NO, 0); // If I keep this line I can see some of teh rotations
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(con, 100, 100); //I want the clock hands to be centered around 100, 100
CGContextRotateCTM(con, 45*index*M_PI/180);
[baseImage drawAtPoint:CGPointMake(0, 0)];
UIImageView *imageView = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
[self.view addSubview:imageView];
imageView.opaque = YES;
imageView.backgroundColor = [UIColor clearColor];
[self.view addSubview:imageView];
}
}


Image showing what is coming on screen. If I use the <code>UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 0);</code> line instead of CGSizeMake(500,600) then all the rotated arrows don't show up

Answer

I am seeing that if I apply a CGContextTranslateCTM to the image graphics context, the image is not drawn

Of course. You draw at 0,0. But first you apply a translate CTM of 100,100. So you actually draw at 100,100. But the context is only 20 points wide. So you are drawing completely outside the context. There is no context outside the context, so nothing is drawn.