UIImageView aspect fit and center
Asked Answered
D

10

203

I have an image view, declared programmatically, and I am setting its image, also programmatically.

However, I find myself unable to set the image to both fit the aspect and align centre to the image view.

In other words, I want the image to:

  • Scale down to fit the aspect, if the image is large.
  • Centre but not scale up, if the image is small.

How do I get that?

Divided answered 19/3, 2013 at 12:21 Comment(2)
[yourImageView setContentMode:UIViewContentModeCenter]; and make sure if imageView Frame is greater than image frame. if it's not then place [yourImageView setContentMode:UIViewContentModeAspectToFit];Infamous
if else condition dude @RyanPoolosInfamous
D
216

Just pasting the solution:

Just like @manohar said

imageView.contentMode = UIViewContentModeCenter;
if (imageView.bounds.size.width > ((UIImage*)imagesArray[i]).size.width && imageView.bounds.size.height > ((UIImage*)imagesArray[i]).size.height) {
       imageView.contentMode = UIViewContentModeScaleAspectFit;
}

solved my problem

Divided answered 19/3, 2013 at 12:35 Comment(4)
Shorter way to find out image is smaller: CGRectContainsRect(imageView.bounds, {CGPointZero, image.size})Lucid
@Lucid maybe it's shorter, but not so readable. At the same time I propose to split line with if-statement like this: CGSize imageSize = ((UIImage*)imagesArray[i]).size;, CGSize viewSize = imageView.bounds.size, if (viewSize.width > imageSize.width && viewSize.height > imageSize.height) {.Furtek
Should be UIViewContentModeScaleAspectFitTatyanatau
imageView.contentMode = UIViewContentModeScaleAspectFit;Donohue
T
83

In swift language we can set content mode of UIImage view like following as:

let newImgThumb = UIImageView(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
newImgThumb.contentMode = .scaleAspectFit
Testaceous answered 14/11, 2014 at 6:0 Comment(1)
This blows up the image if it is smaller than the image view, contrary to what the OP asked for.Smitty
B
40

Swift

yourImageView.contentMode = .center

You can use the following options to position your image:

  • scaleToFill
  • scaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent
  • redraw // redraw on bounds change (calls -setNeedsDisplay)
  • center // contents remain same size. positioned adjusted.
  • top
  • bottom
  • left
  • right
  • topLeft
  • topRight
  • bottomLeft
  • bottomRight
Busywork answered 10/12, 2018 at 11:6 Comment(0)
B
12

Updated answer

When I originally answered this question in 2014, there was no requirement to not scale the image up in the case of a small image. (The question was edited in 2015.) If you have such a requirement, you will indeed need to compare the image's size to that of the imageView and use either UIViewContentModeCenter (in the case of an image smaller than the imageView) or UIViewContentModeScaleAspectFit in all other cases.

Original answer

Setting the imageView's contentMode to UIViewContentModeScaleAspectFit was enough for me. It seems to center the images as well. I'm not sure why others are using logic based on the image. See also this question: iOS aspect fit and center

Bilk answered 26/5, 2014 at 23:14 Comment(2)
This blows up the image if it is smaller than the image view, contrary to what the OP asked for.Smitty
@Smitty The requirement about not scaling the image up was added to the question a year after I answered it: stackoverflow.com/posts/15499376/revisionsBilk
P
10

I solved this problem like this.

  1. setImage to UIImageView (with UIViewContentModeScaleAspectFit)
  2. get imageSize (CGSize imageSize = imageView.image.size)
  3. UIImageView resize. [imageView sizeThatFits:imageSize]
  4. move position where you want.

I wanted to put UIView on the top center of UICollectionViewCell. so, I used this function.

- (void)setImageToCenter:(UIImageView *)imageView
{
    CGSize imageSize = imageView.image.size;
    [imageView sizeThatFits:imageSize];
    CGPoint imageViewCenter = imageView.center;
     imageViewCenter.x = CGRectGetMidX(self.contentView.frame);
    [imageView setCenter:imageViewCenter];
}

It works for me.

Piteous answered 10/3, 2015 at 6:35 Comment(0)
E
9

You can achieve this by setting content mode of image view to UIViewContentModeScaleAspectFill.

Then use following method method to get the resized uiimage object.

- (UIImage*)setProfileImage:(UIImage *)imageToResize onImageView:(UIImageView *)imageView
{
    CGFloat width = imageToResize.size.width;
    CGFloat height = imageToResize.size.height;
    float scaleFactor;
    if(width > height)
    {
        scaleFactor = imageView.frame.size.height / height;
    }
    else
    {
        scaleFactor = imageView.frame.size.width / width;
    }

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(width * scaleFactor, height * scaleFactor), NO, 0.0);
    [imageToResize drawInRect:CGRectMake(0, 0, width * scaleFactor, height * scaleFactor)];
    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return resizedImage;
}

Edited Here (Swift Version)

func setProfileImage(imageToResize: UIImage, onImageView: UIImageView) -> UIImage
{
    let width = imageToResize.size.width
    let height = imageToResize.size.height

    var scaleFactor: CGFloat

    if(width > height)
    {
        scaleFactor = onImageView.frame.size.height / height;
    }
    else
    {
        scaleFactor = onImageView.frame.size.width / width;
    }

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(width * scaleFactor, height * scaleFactor), false, 0.0)
    imageToResize.drawInRect(CGRectMake(0, 0, width * scaleFactor, height * scaleFactor))
    let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return resizedImage;
}
Envelop answered 18/12, 2015 at 13:15 Comment(0)
N
8

This subclass uses center if the image is not larger than the view, otherwise it scales down. I found this useful for a UIImageView that changes the size.

The image it displays is smaller than the view for large sizes, but larger than the view for small sizes. I want it only to scale down, but not up.

class CenterScaleToFitImageView: UIImageView {
    override var bounds: CGRect {
        didSet {
            adjustContentMode()
        }
    }

    override var image: UIImage? {
        didSet {
            adjustContentMode()
        }
    }

    func adjustContentMode() {
        guard let image = image else {
            return
        }
        if image.size.width > bounds.size.width ||
            image.size.height > bounds.size.height {
            contentMode = .ScaleAspectFit
        } else {
            contentMode = .Center
        }
    }
}
Nutriment answered 20/4, 2016 at 10:23 Comment(0)
C
6
let bannerImageView = UIImageView();
bannerImageView.contentMode = .ScaleAspectFit;
bannerImageView.frame = CGRectMake(cftX, cftY, ViewWidth, scrollHeight);
Coakley answered 3/1, 2016 at 13:22 Comment(1)
This blows up the image if it is smaller than the image view, contrary to what the OP asked for.Smitty
I
4
[your_imageview setContentMode:UIViewContentModeCenter];
Irruption answered 9/12, 2013 at 5:58 Comment(2)
This will ignore the scalingNiblick
I don't know why solutions like this got so many upvotes. This person clearly didn't read the question at all.Stipend
D
2

For people looking for UIImage resizing,

@implementation UIImage (Resize)

- (UIImage *)scaledToSize:(CGSize)size
{
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
    [self drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

- (UIImage *)aspectFitToSize:(CGSize)size
{
    CGFloat aspect = self.size.width / self.size.height;
    if (size.width / aspect <= size.height)
    {
        return [self scaledToSize:CGSizeMake(size.width, size.width / aspect)];
    } else {
        return [self scaledToSize:CGSizeMake(size.height * aspect, size.height)];
    }
}

- (UIImage *)aspectFillToSize:(CGSize)size
{
    CGFloat imgAspect = self.size.width / self.size.height;
    CGFloat sizeAspect = size.width/size.height;

    CGSize scaledSize;

        if (sizeAspect > imgAspect) { // increase width, crop height
            scaledSize = CGSizeMake(size.width, size.width / imgAspect);
        } else { // increase height, crop width
            scaledSize = CGSizeMake(size.height * imgAspect, size.height);
        }
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClipToRect(context, CGRectMake(0, 0, size.width, size.height));
    [self drawInRect:CGRectMake(0.0f, 0.0f, scaledSize.width, scaledSize.height)];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

@end
Dutyfree answered 4/4, 2018 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.