代码之家  ›  专栏  ›  技术社区  ›  Greg

如何在iPhone3G上调整大图像的大小而不影响我的应用程序?

  •  2
  • Greg  · 技术社区  · 14 年前

    我正在开发一个应用程序,该应用程序从网站下载图像,以便在iOS设备上显示。该应用在iPad上运行良好,但在iPhone3G上运行时(这是我唯一可以测试的物理设备),加载大图像时会崩溃。正如其他地方所建议的,1024x 1024似乎是它可以持续处理的最大尺寸的图像。

    为了解决这个问题,我添加了代码来调整大于1024宽或1024高的图像的大小(代码取自 here ):

    if (image.size.width > 1024 || image.size.height > 1024) {
        // resize the image
        float actualHeight = image.size.height;
        float actualWidth = image.size.width;
        float imgRatio = actualWidth/actualHeight;
        float maxRatio = self.frame.size.width/self.frame.size.height;
    
        if(imgRatio!=maxRatio) {
            if(imgRatio < maxRatio) {
                  imgRatio = self.frame.size.height / actualHeight;
                  actualWidth = imgRatio * actualWidth;
                  actualHeight = self.frame.size.height;
            } else {
                  imgRatio = self.frame.size.width / actualWidth;
                  actualHeight = imgRatio * actualHeight;
                  actualWidth = self.frame.size.width;
            }
        }
        CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
        UIGraphicsBeginImageContext(rect.size);
        [image drawInRect:rect];
        imageToDraw = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    

    但是,调整非常大的图像的大小(例如,大约3500 x 2500像素的图像)仍然会使应用程序崩溃。

    有没有其他机制可以用来安全地调整如此大的图像的大小,或者其他机制可以用来显示它们而不调整大小?我没有能力在我的应用程序外平铺图像以在CatiledLayer中使用,因为我无法控制图像的来源。

    谢谢!

    编辑: 经过更多的调试,我找到了崩溃的根源(见下面的答案)。但是,我仍然欢迎关于更好的方法的任何建议,允许在iOS设备上查看非常大的图像而不调整图像的大小。

    2 回复  |  直到 10 年前
        1
  •  1
  •   Greg    14 年前

    我刚注意到,有问题的图片有相同的纵横比屏幕(这是在景观方向崩溃时发生的)。自从 imgRatio == maxRatio 对于上述代码中的此图像,未进行大小调整。

    我修改了上面的代码,如下所示:

    if (image.size.width > 1024 || image.size.height > 1024) {
        // resize the image
        float actualHeight = image.size.height;
        float actualWidth = image.size.width;
        float imgRatio = actualWidth/actualHeight;
        float maxRatio = self.frame.size.width/self.frame.size.height;
    
        if(imgRatio < maxRatio){
            imgRatio = self.frame.size.height / actualHeight;
            actualWidth = imgRatio * actualWidth;
            actualHeight = self.frame.size.height;
        }
        else{
            imgRatio = self.frame.size.width / actualWidth;
            actualHeight = imgRatio * actualHeight;
            actualWidth = self.frame.size.width;
        }
        CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
        UIGraphicsBeginImageContext(rect.size);
        [image drawInRect:rect];
        imageToDraw = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    

    现在,它适用于先前让iPhone崩溃的图像。

        2
  •  0
  •   Community CDub    7 年前

    这个 other answer 适用于小图像,但当你试图调整一个非常大的图像,你会很快耗尽内存和崩溃的应用程序。更好的方法是使用 CGImageSourceCreateThumbnailAtIndex 在不完全解码的情况下调整图像大小。

    如果您有要调整大小的图像路径,则可以使用此路径:

    - (void)resizeImageAtPath:(NSString *)imagePath {
        // Create the image source (from path)
        CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);
    
        // To create image source from UIImage, use this
        // NSData* pngData =  UIImagePNGRepresentation(image);
        // CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
    
        // Create thumbnail options
        CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                (id) kCGImageSourceThumbnailMaxPixelSize : @(640)
        };
        // Generate the thumbnail
        CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); 
        CFRelease(src);
        // Write the thumbnail at path
        CGImageWriteToFile(thumbnail, imagePath);
    }
    

    更多细节 here .