【问题标题】:How to resize the image programmatically in objective-c in iphone如何在iphone的objective-c中以编程方式调整图像大小
【发布时间】:2011-06-10 09:14:46
【问题描述】:

我有一个应用程序,我在小空间中显示大图像。 图像非常大,但我只以 100x100 像素帧显示它们。 由于我使用的图像大小,我的应用响应缓慢。

为了提高性能,如何使用 Objective-C 以编程方式调整图像大小?

【问题讨论】:

  • 我编写了一些代码,通过遍历像素并将 4 个像素相加为一个,将图像缩小两倍。它工作得很好(比使用系统缩放更好的图像质量),但可能只有 50 行代码,而且不是很漂亮。 (然后我发现我不需要缩放图像。)
  • 这里是可以找到我的算法的线程:stackoverflow.com/questions/6052188/…
  • @JaspreetSingh 你不应该用你的答案编辑问题 - 你可能想把它作为答案发布

标签: iphone objective-c image


【解决方案1】:

请找到以下代码。

- (UIImage *)imageWithImage:(UIImage *)image convertToSize:(CGSize)size {
    UIGraphicsBeginImageContext(size);
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return destImage;
}

【讨论】:

  • 这在过去是有效的,但在 iOS5.0.1 中这会导致内存泄漏。还有其他方法可以做到这一点吗? stackoverflow.com/questions/8236837/…
  • 这仍然是 iOS 6.x 的问题吗?
【解决方案2】:

此代码仅用于更改图像比例而不用于调整大小。您必须将 CGSize 设置为您的图像宽度和高度,这样图像就不会被拉伸并排列在中间。

- (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size
{
    CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height);
    CGFloat width = image.size.width * scale;
    CGFloat height = image.size.height * scale;
    CGRect imageRect = CGRectMake((size.width - width)/2.0f,
                                  (size.height - height)/2.0f,
                                  width,
                                  height);

    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    [image drawInRect:imageRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

【讨论】:

  • 享受你的编码@NishadArora :)
【解决方案3】:

我最喜欢的方法是使用CGImageSourceCreateThumbnailAtIndex(在 ImageIO 框架中)。这个名字有点误导。

这是我最近的一个应用程序的一些代码的摘录。

CGFloat maxw = // whatever;
CGFloat maxh = // whatever;

CGImageSourceRef src = NULL;
if ([imageSource isKindOfClass:[NSURL class]])
    src = CGImageSourceCreateWithURL((__bridge CFURLRef)imageSource, nil);
else if ([imageSource isKindOfClass:[NSData class]])
    src = CGImageSourceCreateWithData((__bridge CFDataRef)imageSource, nil);

// if at double resolution, double the thumbnail size and use double-resolution image
CGFloat scale = 1;
if ([[UIScreen mainScreen] scale] > 1.0) {
    scale = 2;
    maxw *= 2;
    maxh *= 2;
}

// load the image at the desired size
NSDictionary* d = @{
                    (id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue,
                    (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
                    (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
                    (id)kCGImageSourceThumbnailMaxPixelSize: @((int)(maxw > maxh ? maxw : maxh))
                    };
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d);
if (NULL != src)
    CFRelease(src);
UIImage* im = [UIImage imageWithCGImage:imref scale:scale orientation:UIImageOrientationUp];
if (NULL != imref)
    CFRelease(imref);

【讨论】:

  • 你是如何使用即时通讯的?是 CFRelease(im); ?
【解决方案4】:

如果您使用不同尺寸的图片并且每次都调整大小会降低您的应用性能。解决方案是不要调整它们的大小,只需使用按钮代替 imageview。只需将图像设置在按钮上,它就会自动调整大小,您将获得出色的性能。

我还在单元格上设置图像时调整图像大小,但我的应用程序变慢了所以我使用 Button 代替 imageview(不是以编程方式调整图像大小按钮正在完成这项工作)并且它工作得非常好。

【讨论】:

    【解决方案5】:
       -(UIImage *)scaleImage:(UIImage *)image toSize:.     (CGSize)targetSize
       {
    //If scaleFactor is not touched, no scaling will occur
       CGFloat scaleFactor = 1.0;
    
    //Deciding which factor to use to scale the image (factor = targetSize / imageSize)
    if (image.size.width > targetSize.width || 
       image.size.height > targetSize.height || image.size.width == image.size.height)
        if (!((scaleFactor = (targetSize.width / 
        image.size.width)) > (targetSize.height / 
          image.size.height))) //scale to fit width, or
            scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.
    

    【讨论】:

      【解决方案6】:

      由于代码在 iOS 4 中运行良好,为了向后兼容,我添加了对操作系统版本的检查,对于低于 5.0 的任何内容,旧代码都可以工作。

      - (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality {
          BOOL drawTransposed;
          CGAffineTransform transform = CGAffineTransformIdentity;
      
          if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
              // Apprently in iOS 5 the image is already correctly rotated, so we don't need to rotate it manually
              drawTransposed = NO;  
          } else {    
              switch (self.imageOrientation) {
                  case UIImageOrientationLeft:
                  case UIImageOrientationLeftMirrored:
                  case UIImageOrientationRight:
                  case UIImageOrientationRightMirrored:
                      drawTransposed = YES;
                      break;
      
                  default:
                      drawTransposed = NO;
              }
      
              transform = [self transformForOrientation:newSize];
          } 
      
          return [self resizedImage:newSize
                          transform:transform
                     drawTransposed:drawTransposed
               interpolationQuality:quality];
      }
      

      【讨论】:

        【解决方案7】:

        你可以用这个。

        [m_Image.layer setMinificationFilter:kCAFilterTrilinear];

        【讨论】:

        • 这是用于 UIImageView 而不是 UIImage
        【解决方案8】:

        这个帖子很旧,但它是我在尝试解决这个问题时提出的。一旦图像被缩放,即使我关闭了自动布局,它在我的容器中也不能很好地显示。对我来说,解决此问题以在表格行中显示的最简单方法是将图像绘制在具有固定大小的白色背景上。

        辅助函数

        +(UIImage*)scaleMaintainAspectRatio:(UIImage*)sourceImage :(float)i_width :(float)i_height
        {
        float newHeight = 0.0;
        float newWidth = 0.0;
        
        float oldWidth = sourceImage.size.width;
        float widthScaleFactor = i_width / oldWidth;
        
        float oldHeight = sourceImage.size.height;
        float heightScaleFactor = i_height / oldHeight;
        if (heightScaleFactor > widthScaleFactor) {
            newHeight = oldHeight * widthScaleFactor;
            newWidth = sourceImage.size.width * widthScaleFactor;
        } else {
            newHeight = sourceImage.size.height * heightScaleFactor;
            newWidth = oldWidth * heightScaleFactor;
        }
        
        // return image in white rect
        float cxPad = i_width - newWidth;
        float cyPad = i_height - newHeight;
        if (cyPad > 0) {
            cyPad = cyPad / 2.0;
        }
        if (cxPad > 0) {
            cxPad = cxPad / 2.0;
        }
        
        CGSize size = CGSizeMake(i_width, i_height);
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0);
        [[UIColor whiteColor] setFill];
        UIRectFill(CGRectMake(0, 0, size.width, size.height));
        [sourceImage drawInRect:CGRectMake((int)cxPad, (int)cyPad, newWidth, newHeight)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
        
        // will return scaled image at actual size, not in white rect
        // UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
        // [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
        // UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        // UIGraphicsEndImageContext();
        // return newImage;
        }
        

        我从我的表格视图 cellForRowAtIndexPath 中这样称呼它

            PFFile *childsPicture = [object objectForKey:@"picture"];
        [childsPicture getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
            if (!error) {
                UIImage *largePicture = [UIImage imageWithData:imageData];
                UIImage *scaledPicture = [Utility scaleMaintainAspectRatio:largePicture :70.0 :70.0 ];
                PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
                thumbnailImageView.image = scaledPicture;
                [self.tableView reloadData];
            }
        }];
        

        【讨论】:

          【解决方案9】:

          您好,从 2018 年底开始。 使用下一个解决方案解决(您只需要最后一行,第一行和第二行仅用于说明):

          NSURL *url = [NSURL URLWithString:response.json[0][@"photo_50"]];
          NSData *data = [NSData dataWithContentsOfURL:url];
          UIImage *image = [UIImage imageWithData:data scale:customScale];
          

          'customScale' 是你想要的比例(>1 如果图像必须更小,

          【讨论】:

            【解决方案10】:

            此 c 方法将使用cornerRadius“不影响图像质量”调整图像大小:

            
            UIImage *Resize_Image(UIImage *iImage, CGFloat iSize, CGFloat icornerRadius) {
            
                CGFloat scale = MAX(CGSizeMake(iSize ,iSize).width/iImage.size.width, CGSizeMake(iSize ,iSize).height/iImage.size.height);
                CGFloat width = iImage.size.width * scale;
                CGFloat height = iImage.size.height * scale;
                CGRect imageRect = CGRectMake((CGSizeMake(iSize ,iSize).width - width)/2.0f,(CGSizeMake(iSize ,iSize).height - height)/2.0f,width,height);
                UIGraphicsBeginImageContextWithOptions(CGSizeMake(iSize ,iSize), NO, 0);
                [[UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:icornerRadius] addClip];
                [iImage drawInRect:imageRect];
                UIImage *ResizedImage = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
            
                return ResizedImage;
            }
            

            这是如何使用的:

            UIImage *ResizedImage = Resize_Image([UIImage imageNamed:@"image.png"], 64, 14.4);
            
            • 我不记得前 4 行在哪里..

            【讨论】:

              猜你喜欢
              • 2011-01-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-23
              • 2014-05-30
              • 1970-01-01
              • 2021-04-28
              • 1970-01-01
              相关资源
              最近更新 更多