Reputation: 33644
I wanted to resize a UIImage to a certain width and height keeping the proportion in place. The simplest way to do this is:
CGSize newSize = CGSizeMake(726, 521);
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Does the method above have any drawbacks in terms of image quality and the time it takes? What is a better way than the method above?
EDITED:
How about this one:
- (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 ;
}
Upvotes: 6
Views: 7150
Reputation: 63667
In a performance sample of Image Resizing Techniques the score was
so the fastest and simplest way is:
let renderer = UIGraphicsImageRenderer(size: size)
let resized = renderer.image { (context) in
image.draw(in: CGRect(origin: .zero, size: size))
}
Resize a UIImage the right way is from 2009 but contains useful talk about interpolation quality and preserving the aspect ratio.
Additionally, to preserve the ratio within a max size:
let image: UIImage = ...
let maxSize = CGSize(width: 726, height: 521)
let newSize = AVMakeRect(aspectRatio: image.size, insideRect: CGRect(origin: .zero, size: maxSize)).size
let resized = UIGraphicsImageRenderer(size: newSize).image { _ in
image.draw(in: CGRect(origin: .zero, size: newSize))
}
To change the pixels per point density (default is the ppp of the current screen):
let format = UIGraphicsImageRendererFormat()
format.scale = 1
UIGraphicsImageRenderer(size: newSize, format: format)
...
Upvotes: 13
Reputation: 387
Here is a simple way:
UIImage * image = [UIImage imageNamed:@"image"];
CGSize sacleSize = CGSizeMake(10, 10); // scale image to 10 x 10
UIGraphicsBeginImageContextWithOptions(sacleSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, sacleSize.width, sacleSize.height)];
UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
resizedImage is a new image.
Upvotes: 0