PDA

View Full Version : Applying a rotation transform results in blank screen




tutiplain
Jul 25, 2011, 11:04 PM
Hi all,

I am playing with affine transformations. Right now, I am trying to rotate an image, by say, 90 degrees. I have made a UIView subclass and overridden its drawRect: method like so:


- (void)drawRect:(CGRect)rect
{
// Drawing code

CGContextRef context;
context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

CGAffineTransform t0 =CGContextGetCTM(context);
t0 =CGAffineTransformInvert(t0);
CGContextConcatCTM(context, t0);

CGAffineTransform t1 = CGAffineTransformIdentity;
//t1= CGAffineTransformMakeRotation(90);
//t1 = CGAffineTransformMakeTranslation(100, 100);
//t1=CGAffineTransformMakeScale(2, 3);
//CGContextConcatCTM(context, t1);
CGContextRotateCTM(context, 3.141592);

NSString *img_path = [[NSBundle mainBundle] pathForResource:@"image_preview" ofType:@"jpg"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:img_path];

CGImageRef img_ref = [image CGImage];
CGRect rectangle = CGRectMake(120, 120, 200, 200);
CGContextDrawImage(context, rectangle, img_ref);


//This approach works
//UIImageView *img_view = [[UIImageView alloc] initWithImage:image];
//[self addSubview:img_view];
//[img_view setTransform:t1];


CGContextRestoreGState(context);

}



When I run this code, the simulator screen remains blank. If I comment out the call to CGContextRotateCTM and uncomment any of the other transformations, they work, and the image is displayed properly, except the transformation made by CGAffineTransformMakeRotation. If I use the commented code below, which relies on a UIImageView object to do the transform, it works.

I don't understand why it wouldn't work with the CGContextRotateCTM or CGAffineTransformMakeRotation functions. Can anyone shed any light on this? It will be greatly appreciated. Thanks!



robbieduncan
Jul 26, 2011, 04:31 AM
What point are you rotating the view around?

tutiplain
Jul 26, 2011, 07:59 AM
What do you mean? I take it you mean that I need to specify a rotation center or origin. Is this what I'm missing? How would I specify this? Why doesn't the image view require it to work? Thanks again!

robbieduncan
Jul 26, 2011, 08:07 AM
What do you mean? I take it you mean that I need to specify a rotation center or origin. Is this what I'm missing? How would I specify this? Why doesn't the image view require it to work? Thanks again!

I think we need to separate the application of a transform to a view and the use of a coordinate transform within the drawing of a view. The first one transforms the view frame but no the coordinate system that the view draws within. In effect the view draws to a backing store that is then composited with the transform applied. What you are doing is transforming the coordinate system for drawing. Such a transform is logically applied around (0,0) (a corner of the view). So you are now drawing to coordinates that are not actually visible within the views frame and bounds.

tutiplain
Jul 27, 2011, 06:50 AM
Hi,

I'm trying to reproduce what you said, about using a different coordinate system. I understand the theory of how it works, but have doubts how to apply that to CGAffineTransform. I mean, the way I understood it, affine transforms always need to be concatenated to the CTM, so if I want to draw a rotated image, I rotate my view using affine transformations, draw as I normally would, then restore using CGContextRestoreGState(). Now, I understand how rotating my view at (0,0) will cause my rotated image to fall outside visual bounds, but still don't know how using a different coordinate system will help make the image stay in view, since all affine transformations still need to be applied to the current transformation matrix (please excuse my ignorance on this issue).

Either way, I am setting the code I showed previously to use a different coordinate system. Perhaps that will make things clearer.

robbieduncan
Jul 27, 2011, 06:56 AM
...Now, I understand how rotating my view at (0,0) will cause my rotated image to fall outside visual bounds, but still don't know how using a different coordinate system will help make the image stay in view, since all affine transformations still need to be applied to the current transformation matrix (please excuse my ignorance on this issue)...

But what if the current transform were not around (0,0)? Lets imagine we want to draw a square centred on (10,10) but rotated. What we can do is save the CTM state, translate the CTM by (10,10), rotate the CTM then draw our square. Note at this point we draw our square centred on (0,0) as we have translated the CTM. We then pop the CTM state back.

This is, in general, how this sort of operation is performed. It is also documented by Apple in the Drawing and Printing Guide for iOS (http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW1) (scroll down to Coordinates and Coordinate Transforms).