How to scale a UIImageView proportionally?

Objective CCocoa Touch

Objective C Problem Overview


I have a UIImageView and the objective is to scale it down proportionally by giving it either a height or width.

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];	

//Add image view
[self.view addSubview:imageView];	

//set contentMode to scale aspect to fit
imageView.contentMode = UIViewContentModeScaleAspectFit;

//change width of frame
CGRect frame = imageView.frame;
frame.size.width = 100;
imageView.frame = frame;

The image did get resized but the position is not at the top left. What is the best approach to scaling image/imageView and how do I correct the position?

Objective C Solutions


Solution 1 - Objective C

Fixed easily, once I found the documentation!

 imageView.contentMode = .scaleAspectFit

Solution 2 - Objective C

I've seen a bit of conversation about scale types so I decided to put together an article regarding some of the most popular content mode scaling types.

The associated image is here:

enter image description here

Solution 3 - Objective C

I just tried this, and UIImage does not support _imageScaledToSize.

I ended up adding a method to UIImage using a category - a suggestion I found on the Apple Dev forums.

In a project-wide .h -

@interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
@end;

Implementation:

@implementation UIImage (Extras)

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {

	UIImage *sourceImage = self;
	UIImage *newImage = nil;
	
	CGSize imageSize = sourceImage.size;
	CGFloat width = imageSize.width;
	CGFloat height = imageSize.height;
	
	CGFloat targetWidth = targetSize.width;
	CGFloat targetHeight = targetSize.height;
	
	CGFloat scaleFactor = 0.0;
	CGFloat scaledWidth = targetWidth;
	CGFloat scaledHeight = targetHeight;
	
	CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
	
	if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
		
		CGFloat widthFactor = targetWidth / width;
		CGFloat heightFactor = targetHeight / height;
		
		if (widthFactor < heightFactor) 
			scaleFactor = widthFactor;
		else
			scaleFactor = heightFactor;
		
		scaledWidth  = width * scaleFactor;
		scaledHeight = height * scaleFactor;
		
		// center the image
		
		if (widthFactor < heightFactor) {
			thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
		} else if (widthFactor > heightFactor) {
			thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
		}
	}
	
	
	// this is actually the interesting part:
	
	UIGraphicsBeginImageContext(targetSize);
	
	CGRect thumbnailRect = CGRectZero;
	thumbnailRect.origin = thumbnailPoint;
	thumbnailRect.size.width  = scaledWidth;
	thumbnailRect.size.height = scaledHeight;
	
	[sourceImage drawInRect:thumbnailRect];
	
	newImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	
	if(newImage == nil) NSLog(@"could not scale image");
	
	
	return newImage ;
}

@end;

Solution 4 - Objective C

imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;

Solution 5 - Objective C

You could try making the imageView size match the image. The following code is not tested.

CGSize kMaxImageViewSize = {.width = 100, .height = 100};
CGSize imageSize = image.size;
CGFloat aspectRatio = imageSize.width / imageSize.height;
CGRect frame = imageView.frame;
if (kMaxImageViewSize.width / aspectRatio <= kMaxImageViewSize.height) 
{
    frame.size.width = kMaxImageViewSize.width;
    frame.size.height = frame.size.width / aspectRatio;
} 
else 
{
    frame.size.height = kMaxImageViewSize.height;
    frame.size.width = frame.size.height * aspectRatio;
}
imageView.frame = frame;

Solution 6 - Objective C

This works fine for me Swift 2.x:

imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true;

Solution 7 - Objective C

one can resize an UIImage this way

image = [UIImage imageWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp];

Solution 8 - Objective C

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 


//set contentMode to scale aspect to fit
imageView.contentMode = UIViewContentModeScaleAspectFit;

//change width of frame
//CGRect frame = imageView.frame;
//frame.size.width = 100;
//imageView.frame = frame;

//original lines that deal with frame commented out, yo.
imageView.frame = CGRectMake(10, 20, 60, 60);

...

//Add image view
[myView addSubview:imageView]; 

The original code posted at the top worked well for me in iOS 4.2.

I found that creating a CGRect and specifying all the top, left, width, and height values was the easiest way to adjust the position in my case, which was using a UIImageView inside a table cell. (Still need to add code to release objects)

Solution 9 - Objective C

Set your ImageView by selecting Mode to Aspect Fill and check the Clip Subviews box.

enter image description here

Solution 10 - Objective C

Set your UIimageview by scale.........

enter image description here

Solution 11 - Objective C

For Swift :

self.imageViews.contentMode = UIViewContentMode.ScaleToFill

Solution 12 - Objective C

UIImageView+Scale.h:

#import <Foundation/Foundation.h>

@interface UIImageView (Scale)

-(void) scaleAspectFit:(CGFloat) scaleFactor;

@end

UIImageView+Scale.m:

#import "UIImageView+Scale.h"

@implementation UIImageView (Scale)


-(void) scaleAspectFit:(CGFloat) scaleFactor{

    self.contentScaleFactor = scaleFactor;
    self.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);

    CGRect newRect = self.frame;
    newRect.origin.x = 0;
    newRect.origin.y = 0;
    self.frame = newRect;
}

@end

Solution 13 - Objective C

If the solutions proposed here aren't working for you, and your image asset is actually a PDF, note that XCode actually treats PDFs differently than image files. In particular, it doesn't seem able to scale to fill properly with a PDF: it ends up tiled instead. This drove me crazy until I figured out that the issue was the PDF format. Convert to JPG and you should be good to go.

Solution 14 - Objective C

I used following code.where imageCoverView is UIView holds UIImageView

if (image.size.height<self.imageCoverView.bounds.size.height && image.size.width<self.imageCoverView.bounds.size.width)
{
    [self.profileImageView sizeToFit];
    self.profileImageView.contentMode =UIViewContentModeCenter
}
else
{
    self.profileImageView.contentMode =UIViewContentModeScaleAspectFit;
}

Solution 15 - Objective C

Usually I use this method for my apps (Swift 2.x compatible):

// Resize UIImage
func resizeImage(image:UIImage, scaleX:CGFloat,scaleY:CGFloat) ->UIImage {
    let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(scaleX, scaleY))
    let hasAlpha = true
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
    
    UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
    image.drawInRect(CGRect(origin: CGPointZero, size: size))
    
    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return scaledImage
}

Solution 16 - Objective C

I think you can do something like

image.center = [[imageView window] center];

Solution 17 - Objective C

Here is how you can scale it easily.

This works in 2.x with the Simulator and the iPhone.

UIImage *thumbnail = [originalImage _imageScaledToSize:CGSizeMake(40.0, 40.0) interpolationQuality:1];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRonnie LiewView Question on Stackoverflow
Solution 1 - Objective CKen AbramsView Answer on Stackoverflow
Solution 2 - Objective CJacksonkrView Answer on Stackoverflow
Solution 3 - Objective CJane SalesView Answer on Stackoverflow
Solution 4 - Objective CLi-chih WuView Answer on Stackoverflow
Solution 5 - Objective CChris LundieView Answer on Stackoverflow
Solution 6 - Objective CvvamondesView Answer on Stackoverflow
Solution 7 - Objective CneoneyeView Answer on Stackoverflow
Solution 8 - Objective CNate FlinkView Answer on Stackoverflow
Solution 9 - Objective CJeffrey NeoView Answer on Stackoverflow
Solution 10 - Objective CP.J.RadadiyaView Answer on Stackoverflow
Solution 11 - Objective CSomir SaikiaView Answer on Stackoverflow
Solution 12 - Objective CPeter KreinzView Answer on Stackoverflow
Solution 13 - Objective CLane RettigView Answer on Stackoverflow
Solution 14 - Objective CAvijit NagareView Answer on Stackoverflow
Solution 15 - Objective CAlessandro OrnanoView Answer on Stackoverflow
Solution 16 - Objective Cuser26359View Answer on Stackoverflow
Solution 17 - Objective CkdbdallasView Answer on Stackoverflow