如何等比例缩放UIImageView?

349

我有一个UIImageView,目标是通过给定高度或宽度来等比例缩小它。

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;

图片已经被缩放,但位置不在左上角。缩放图像/ imageView的最佳方法是什么,如何更正位置?


我有类似于你的代码,但对我不起作用。"UIImage *image = [UIImage imageNamed:imageString]; UIImageView *imageView = [[UIImage alloc] initWithImage:image];" 抛出了一个异常,导致我的应用程序崩溃,并显示如下错误信息:"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImage initWithImage:]: unrecognized selector sent to instance 0xd815930'" - Spire
3
@Spire说的是UIImageView而不是UIImage ^^ - Thomas Decaux
2
这对我有效。记得将.contentMode设置为你的UIImageView,而不是UIImage。这是我的代码:UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,30,30)] - JBB
17个回答

547

一旦我找到了文档,问题就很容易解决了!

 imageView.contentMode = .scaleAspectFit

20
你实际上回答了什么?Ronnie在他的问题中提到他使用它。 - Dejell
3
您的imageView可能没有进行裁剪。尝试使用imageView.layer.masksToBounds = YES;来裁剪。 - mackworth
我最初尝试使用IB确保它按照需要工作,但我不记得要设置的变量名。所以我谷歌了一下并找到了这个答案。 - Dino Tw
1
对于在Swift中遇到相同问题的任何人:ScaleAspectFit现在是一个enum UIViewContentMode,因此您可以设置imageView.contentMode = UIViewContentMode.ScaleAspectFit。请注意句号。 - sudo make install
2
不应将translatesAutoresizingMaskIntoConstraints设置为false。花了很长时间才意识到这个属性阻止了调整大小。 - Gerald

401

我想使用Aspect Fill,但我也想显示完整的图像。那么我需要更改“适合区域”的大小。如何在自动布局中实现这一点? - lee
@lee,有很多选择,但真正取决于你的情况。我创建了一个SOF聊天室,这样我们就可以讨论你的话题,我会提供我所拥有的信息,如果你愿意,请过来参加:http://chat.stackoverflow.com/rooms/81180/ios-autoresize-chat - Jacksonkr
@Jackson,这并不是自动发生的。UIImageView在缩放之前会选择原始图像的高度,因此高度与新的Aspect Fitted高度不匹配。如果有人找到了一个好的方法,请告诉我。 - datWooWoo
对于Aspect Fill: “通常会裁剪一侧,但从不同时裁剪两侧”这种说法是不准确的。我测试过了,裁剪后的图像会自动居中,两侧都被裁剪(就像Google图片所示)。 - pixelfreak
@pixelfreak 我明白你的意思。为了消除歧义,使用了“side”而本可以使用“axis”。进一步思考,图像被缩小直到一个轴适合(而不是裁剪)。 - Jacksonkr
显示剩余2条评论

78

我尝试过这个方法,但UIImage并不支持_imageScaledToSize。

最终我使用了一个类别(category)为UIImage添加了一个方法 - 这是我在苹果开发者论坛上找到的建议。

在全局.h文件中添加:

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

实现:

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

1
为了支持Retina显示屏而不使其模糊,可以使用以下代码替换UIGraphicsBeginImageContext(targetSize);if ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); } - bicycle

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

30

您可以尝试使imageView的大小与image匹配。以下代码未经过测试。

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;

1
设置imageView.frame = XXXX(任何值)对输出没有任何影响。有什么想法为什么? - sramij
1
如果您正在使用自动布局,请确保在UIView上使用[setTranslatesAutoResize ...]。 如果您不知道它的作用,请查看文档! :) - datWooWoo

14

对我来说,这在Swift 2.x中运行良好:

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

13

可以通过以下方式调整 UIImage 的大小

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

13
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]; 

对我来说,顶部发布的原始代码在iOS 4.2上运行良好。

我发现创建一个CGRect并指定所有的上边距、左边距、宽度和高度值是调整位置的最简单方法,我的情况是在表格单元格中使用UIImageView。(仍需要添加释放对象的代码)


13

选择模式为Aspect Fill并勾选Clip Subviews框,即可通过ImageView设置图片。

输入图像描述


12

通过缩放设置您的 UIimageview......

在此输入图片描述


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