【问题标题】:How to scale a UIImageView proportionally?如何按比例缩放 UIImageView?
【发布时间】:2010-09-16 04:27:13
【问题描述】:

我有一个 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;

图像确实已调整大小,但位置不在左上角。缩放 image/imageView 的最佳方法是什么?如何更正位置?

【问题讨论】:

  • 我有一些类似于你的代码对我不起作用“UIImage *image = [UIImage imageNamed:imageString]; UIImageView *imageView = [[UIImage alloc] initWithImage:image];”引发一个异常,该异常会杀死我的应用程序,因为“由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'-[UIImage initWithImage:]: unrecognized selector sent to instance 0xd815930'”
  • @Spire 这是 UIImageView 不是 UIImage ^^
  • 这对我有用。请记住将 .contentMode 设置为您的 UIImageView - 而不是您的 UIImage。 -- 这是我的: UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,30,30)]

标签: objective-c cocoa-touch


【解决方案1】:

一旦找到文档,就可以轻松修复!

 imageView.contentMode = .scaleAspectFit

【讨论】:

  • 你实际回答了什么?在 Ronnie 的问题中,他提到他使用它
  • 您的 imageView 可能没有剪辑。试试 imageView.layer.masksToBounds = YES;
  • 我第一次尝试使用 IB 以确保它可以根据需要工作,但我不记得要设置的变量名称。所以我谷歌它并找到了这个答案。
  • 对于任何在 Swift 中遇到同样问题的人:ScaleAspectFit 现在是 enum UIViewContentMode,所以你可以设置 imageView.contentMode = UIViewContentMode.ScaleAspectFit。注意句号。
  • translatesAutoresizingMaskIntoConstraints 不应设置为 false。我花了很长时间才意识到这个属性会阻止调整大小
【解决方案2】:

我看到了一些关于比例类型的讨论,所以我决定整理一个article regarding some of the most popular content mode scaling types

相关图片在这里:

【讨论】:

  • 设置 AspectFit 时如何垂直对齐?
  • @esbenr 这应该会自动发生。您可能可以根据需要找到替代方案,但我目前不知道:|
  • 我想使用 Aspect Fill 但我也想显示完整的图像。然后我需要更改“适合的区域”大小。如何使用自动布局做到这一点?
  • @lee 有很多选择,但这取决于您的具体情况。我创建了一个 SOF 聊天,这样我们就可以讨论你的话题,我会给你想要的信息,如果你愿意的话,就去吧:chat.stackoverflow.com/rooms/81180/ios-autoresize-chat
  • @Jackson 这根本不会自动发生。它在 UIImageView 缩放它之前选择原始图像的高度,因此高度与新的 Aspect Fitted 高度不匹配。如果有人想出一个很好的方法来做到这一点,请告诉我。
【解决方案3】:

我刚试过,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;

【讨论】:

  • 而不是UIGraphicsBeginImageContext(targetSize); do if ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); } 以支持视网膜显示而不会使其模糊
【解决方案4】:
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;

【讨论】:

    【解决方案5】:

    您可以尝试使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;
    

    【讨论】:

    • 设置 imageView.frame = XXXX (anything) 对输出没有任何不同。知道为什么吗?
    • @sramij 如果您使用自动布局,请确保在 UIViews 上使用 [setTranslatesAutoResize...]。如果你不知道那是什么检查文档! :)
    【解决方案6】:

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

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

    【讨论】:

      【解决方案7】:
      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。 (还是需要添加代码来释放对象)

      【讨论】:

        【解决方案8】:

        通过将模式选择为 Aspect Fill 并选中 Clip Subviews 框来设置您的 ImageView。

        【讨论】:

          【解决方案9】:

          这适用于我 Swift 2.x:

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

          【讨论】:

            【解决方案10】:

            按比例设置您的UIimageview.........

            【讨论】:

              【解决方案11】:

              对于斯威夫特:

              self.imageViews.contentMode = UIViewContentMode.ScaleToFill
              

              【讨论】:

                【解决方案12】:

                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
                

                【讨论】:

                  【解决方案13】:

                  我使用了以下代码。其中 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;
                  }
                  

                  【讨论】:

                    【解决方案14】:

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

                    【讨论】:

                      【解决方案15】:

                      通常我将这种方法用于我的应用程序(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
                      }
                      

                      【讨论】:

                        【解决方案16】:

                        我认为你可以做类似的事情

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

                        【讨论】:

                        • 它不会缩放图像,只会居中。
                        【解决方案17】:

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

                        这适用于模拟器和 iPhone 的 2.x。

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

                        【讨论】:

                        • 嗨,你知道interpolationQuality: 参数的作用吗?谢谢
                        • 这是一种未记录的方法(下划线是一个致命的赠品),可能会导致应用被拒绝。
                        • interpolationQuality 参数有什么作用?
                        猜你喜欢
                        • 2015-10-08
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2023-03-22
                        • 1970-01-01
                        • 2011-08-26
                        • 2014-02-13
                        相关资源
                        最近更新 更多