UIImageView等比例缩放并居中显示

201
我有一个以编程方式声明的ImageView,并且我也通过编程设置了它的图像。 但是,我发现无法同时将图像设置为适合纵横比并居中到图像视图。
换句话说,我希望图像具有以下效果:
  • 如果图片很大,则缩小以适应比例。
  • 如果图片很小,则保持居中而不放大。
如何做到这一点?

19
[yourImageView setContentMode:UIViewContentModeCenter]; 并确保如果 imageView 的框架大于图像框架,则执行此操作。如果不是,则放置 [yourImageView setContentMode:UIViewContentModeAspectToFit]; - Manu
1
如果-否则条件,伙计 @RyanPoolos - Manu
10个回答

216

仅粘贴解决方案:

就像@manohar所说的那样

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;
}

解决了我的问题


7
查找图像是否较小的更简短方法:CGRectContainsRect(imageView.bounds, {CGPointZero, image.size}) - Cfr
@Cfr也许代码更短,但不太易读。同时,我建议将if语句拆分成以下几行:CGSize imageSize = ((UIImage*)imagesArray[i]).size;CGSize viewSize = imageView.bounds.sizeif (viewSize.width > imageSize.width && viewSize.height > imageSize.height) { - Timur Bernikovich
1
应该是UIViewContentModeScaleAspectFit。 - NoelHunter
1
imageView.contentMode = UIViewContentModeScaleAspectFit; imageView.contentMode = UIViewContentModeScaleAspectFit; - Arjay Waran

83

在 Swift 语言中,我们可以通过以下方式设置 UIImage 视图的内容模式:

let newImgThumb = UIImageView(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
newImgThumb.contentMode = .scaleAspectFit

4
这会放大图片,即使它比图像视图小,这与原帖的要求相反。 - fishinear

39

Swift

->

Swift

yourImageView.contentMode = .center

您可以使用以下选项来定位您的图像:

  • scaleToFill
  • scaleAspectFit // 内容按比例缩放以适应固定纵横比。剩余部分是透明的
  • redraw // 当边界改变时重新绘制 (调用 -setNeedsDisplay)
  • center // 内容保持原始大小。位置会自动调整
  • top
  • bottom
  • left
  • right
  • topLeft
  • topRight
  • bottomLeft
  • bottomRight

12

更新的答案

当我在2014年回答这个问题时,没有要求在小图像的情况下不放大图像。(该问题在2015年被编辑。) 如果您有这样的要求,您确实需要将图像的大小与imageView的大小进行比较,并在图像小于imageView的情况下使用UIViewContentModeCenter(在所有其他情况下使用UIViewContentModeScaleAspectFit)。

原始答案

将imageView的contentMode设置为UIViewContentModeScaleAspectFit就足够了。它似乎也会居中显示图像。我不确定为什么其他人要根据图像使用逻辑。另请参阅此问题:iOS aspect fit and center


1
这会放大图片,即使它比图像视图小,与 OP 所要求的相反。 - fishinear
1
@fishinear 在我回答这个问题一年之后,有一个关于不将图像放大的要求被添加到了问题中:https://stackoverflow.com/posts/15499376/revisions - Nate Cook

10

我是这样解决这个问题的。

  1. UIImageView设置为图像视图(使用UIViewContentModeScaleAspectFit
  2. 获取图像大小(CGSize imageSize = imageView.image.size)
  3. UIImageView调整大小。 [imageView sizeThatFits:imageSize]
  4. 移动到所需位置。

我想将UIView放置在UICollectionViewCell的顶部中心。 因此,我使用了这个函数。

- (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];
}

对我而言,它有效。


9
您可以通过将图像视图的内容模式设置为UIViewContentModeScaleAspectFill来实现此目的。 然后使用以下方法获取调整大小的UIImage对象。
- (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;
}

编辑此处(Swift 版本)

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;
}

8

如果图像不大于视图,则此子类使用中心对齐,否则会缩小。我发现这对于更改大小的 UIImageView 很有用。

它显示的图像对于大尺寸来说比视图小,但对于小尺寸来说比视图大。我希望它只缩小而不放大。

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
        }
    }
}

6
let bannerImageView = UIImageView();
bannerImageView.contentMode = .ScaleAspectFit;
bannerImageView.frame = CGRectMake(cftX, cftY, ViewWidth, scrollHeight);

这会放大图像,即使它比图像视图小,与 OP 所要求的相反。 - fishinear

4
[your_imageview setContentMode:UIViewContentModeCenter];

19
这将忽略缩放。 - Skrew
2
我不知道为什么像这样的解决方案会得到那么多赞。这个人显然根本没有读懂问题。 - slow

2

对于需要调整UIImage大小的用户,

@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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接