如何按比例缩放UIImageView?


341

我有一个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];” 抛出一个实例杀死了我的应用程序,这是“由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'-[UIImage initWithImage:]:无法识别的选择器发送到实例0xd815930'”
尖顶

3
@Spire是UIImageView而不是UIImage ^^
Thomas Decaux

2
这对我有用。请记住将.contentMode设置为UIImageView而不是UIImage。-这是我的:UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,30,30)]
Jarrett Barnett

Answers:


541

找到文档后,轻松修复!

 imageView.contentMode = UIViewContentModeScaleAspectFit;

19
您实际回答了什么?在罗尼(Ronnie)的问题中,他提到他使用了它
Dejell

3
您的imageView可能没有被剪切。尝试imageView.layer.masksToBounds = YES;
mackworth 2014年

我首先尝试使用IB来确保它可以根据需要运行,但是我不记得要设置的变量名称。因此,我用Google搜索并找到了这个答案。
Dino Tw

1
对于在Swift中遇到相同问题的任何人:ScaleAspectFit现在是an enum UIViewContentMode,因此您可以设置imageView.contentMode = UIViewContentMode.ScaleAspectFit。注意期间。
sudo make install

1
translatesAutoresizingMaskIntoConstraints不应设置为false。我花了很长时间才意识到此属性阻止了大小调整
Gerald

401

我已经了解了一些关于缩放类型的话题,因此我决定撰写一篇关于一些最流行的内容模式缩放类型的文章

相关的图像在这里:

在此处输入图片说明


设置AspectFit后如何垂直对齐?
esbenr

@esbenr那应该自动发生。您也许可以根据需要找到一个替代,但我目前不知道一个替代:|
Jacksonkr

我想使用纵横比填充,但我也想显示完整图像。然后,我需要更改“适合区域”的大小。我该如何使用自动布局?

@lee有很多选择,但这实际上取决于您的情况。我创建了一个SOF聊天室,以便我们讨论您的主题,我将为您提供所需的信息,如果您愿意的话,请继续进行:chat.stackoverflow.com/rooms/81180/ios-autoresize-chat
Jacksonkr

@Jackson根本不会自动发生。它会在UIImageView缩放之前选择原始图像的高度,因此该高度与新的Aspect Fit高度不匹配。如果有人想出一种不错的方法,请告诉我。
datWooWoo

78

我只是试过了,UIImage不支持_imageScaledToSize。

我最终使用类别向UIImage添加了一种方法-我在Apple Dev论坛上发现了一个建议。

在整个项目的.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
而不是在UIGraphicsBeginImageContext(targetSize);([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }使视网膜显示模糊的情况下支持它
自行车

38
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 2014年

1
@sramij如果您使用的是自动布局,请确保与UIViews上的[setTranslatesAutoResize ...]混淆。如果您不知道该怎么做,请查阅文档!:)
datWooWoo

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。(仍然需要添加代码以释放对象)



10

这对我的Swift 2.x正常工作:

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



5

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

2

我使用以下代码。其中imageCoverView是UIView持有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;
}

2

如果此处提出的解决方案不适合您,并且您的图像资产实际上是PDF,请注意,XCode实际上将PDF与图像文件区别对待。特别是,它似乎无法缩放以正确填充PDF:它最终以平铺显示。这让我发疯,直到我发现问题出在PDF格式。转换为JPG,您应该一切顺利。


1

通常,我对我的应用程序使用此方法(与Swift 2.x兼容):

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

0

我想你可以做类似的事情

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

3
它不会缩放图像,而只会将其居中。
大卫·萨尔泽

-3

这是您可以轻松扩展的方法。

在Simulator和iPhone中的2.x版本中可以使用。

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

您好,您知道InterpolationQuality:参数的作用吗?谢谢
user102008

27
这是一个未记录的方法(下划线是无用的赠品),可能导致应用拒绝。
毛茸茸的青蛙,

interpolationQuality参数有什么作用?
lostInTransit 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.