Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why after rotating UIImageView size is getting changed?

I'm new in using transformations. And still confusted how they are working.

What I'm trying to do, is to rotate my UIImageView with given angle. But after rotating, it's changing the size of image, getting smaller. I'm also doing scaling for ImageView so it won't be upside down.How to rotate and keep the size, that was given in CGRectMake, when ImageView was allocated ?

    UIImageView *myImageView = [[UIImageView alloc]initWithFrame:CGRectMake(x,y,width,height)];        

    myImageView.contentMode = UIViewContentModeScaleAspectFit;

    [myImageView setImage:[UIImage imageNamed:@"image.png"]];

    myImageView.layer.anchorPoint = CGPointMake(0.5,0.5);

    CGAffineTransform newTransform;

    myImageView.transform = CGAffineTransformMakeScale(1,-1);            

    newTransform = CGAffineTransformRotate(newTransform, 30*M_PI/180);

    [self.window addSubview:myImageView];

Thanks a lot!

like image 357
User1234 Avatar asked May 13 '12 07:05

User1234


People also ask

How do I change aspect ratio in UIImageView?

If you are resizing UIImageView manually, set the content mode to UIViewContentModeScaleAspectFill . If you want to keep content mode UIViewContentModeScaleAspectFit do not resize imageview to 313. Image will adjust maximum possible width and height , keeping it's aspect ratio.

What is the difference between a UIImage and a UIImageView?

UIImage contains the data for an image. UIImageView is a custom view meant to display the UIImage .


1 Answers

Ok I promised I'd look into it, so here's my answer:

I create a scene which should be somewhat equivalent to yours, code as follows:

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width/2-100,
                                                                       self.view.bounds.size.height/2-125,
                                                                       200,
                                                                       250)];

imageView.image = [UIImage imageNamed:@"testimage.jpg"];
imageView.contentMode = UIViewContentModeScaleAspectFill;

/*
 * I added clipsToBounds, because my test image didn't have a size of 200x250px
 */
imageView.clipsToBounds = YES;

[self.view addSubview:imageView];

NSLog(@"frame: %@",[NSValue valueWithCGRect:imageView.frame]);
NSLog(@"bounds: %@",[NSValue valueWithCGRect:imageView.bounds]);    

imageView.layer.anchorPoint = CGPointMake(0.5, 0.5);
imageView.transform = CGAffineTransformMakeRotation(30*M_PI/180);

NSLog(@"frame after rotation: %@",[NSValue valueWithCGRect:imageView.frame]);
NSLog(@"bounds after rotation: %@",[NSValue valueWithCGRect:imageView.bounds]); 

This code assumes that you are using ARC. If not add

[imageView release];   

at the end.

Using this code the logs look like this:

[16221:207] frame: NSRect: {{60, 105}, {200, 250}}
[16221:207] bounds: NSRect: {{0, 0}, {200, 250}}
[16221:207] frame after rotation: NSRect: {{10.897461, 71.746826}, {298.20508, 316.50635}}
[16221:207] bounds after rotation: NSRect: {{0, 0}, {200, 250}}    

As you can see the bounds always stay the same. What actually changes due to the rotation is the frame, because an image which has been rotated by 30°C is of course wider than if it handn't been rotated. And since the center point has been set to the actual center of the view the origin of the frame also changes (being pushed to the left and the top). Notice that the size of the image itself does not change. I didn't use the scale transformation, since the result can be achieved without scaling.

But to make it clearer here are some pictures for you (0°, 30° 90° rotation): 0°,30° and 90° rotations of UIImageView

They already look pretty similar, right? I drew the actual frames to make it clear what's the difference between bounds and frame is. The next one really makes it clear. I overlayed all images, rotating them by the negative degrees with which the UIImageView was rotated, giving the following result: UIImageViews overlayed to show that size doesn't change

So you see it's pretty straight forward how to rotate images. Now to your problem that you actually want the frame to stay the same. If you want the final frame to have the size of your original frame (in this example with a width of 200 and a height of 250) then you will have to scale the resulting frame. But this will of course result in scaling of the image, which you do not want. I actually think a larger frame will not be a problem for you - you just need to know that you have to take it into account because of the rotation.

In short: it is not possible to have an UIImageView which will have the same frame after rotation. This isn't possible for any UIView. Just think of a rectangle. If you rotate it, it won't be a rectangle after the rotation, will it?

Of course you could put your UIImageView inside another UIView which will have a non-rotated frame with a width of 200 and a height of 250 but that would just be superficial, since it won't really change the fact that a rotated rectangle has a different width and height than the original.

I hope this helps. :)

like image 82
Johannes Lumpe Avatar answered Nov 15 '22 08:11

Johannes Lumpe