2016-07-01 61 views
2

我有一個從Web資源(> 300MBs)下載的大量UIImage,當我嘗試渲染時,會導致應用程序因內存崩潰。我嘗試使用下面的代碼來調整圖像大小:在內存限制下調整UIImage的大小

+ (UIImage *)imageWithImage:(UIImage *)image scaled:(float) scale { 
    //UIGraphicsBeginImageContext(newSize); 
    CGSize size = (CGSize){scale * image.size.width, scale * image.size.height}; 
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); 
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 

的問題是,你可能已經猜到了,這需要實際渲染圖像,從而導致死機一樣。有沒有辦法調整大圖像而不會在系統上造成如此巨大的內存壓力?

+1

是不是有沒有下載圖像瓷磚的原因?!? – Wain

+0

是的,我作爲一個base64編碼的字符串獲得整體圖像 – Iowa15

回答

4

試試這個+ (UIImage *)decodedImageWithImage:(UIImage *)image maxSize:(NSInteger) maxSize.代碼的問題是你持有在內存中的圖像。將它下載到磁盤並使用ImageIO框架直接從磁盤讀取「縮略圖」(較小的尺寸),而無需將全尺寸圖像保存在內存中。

+0

謝謝,這對我有用,並幫助我解決了頭痛問題! – Iowa15

0

您可以從SDWebImage

#define MAX_IMAGE_SIZE 1000 
@implementation UIImage (ForceDecode) 
+ (CGSize) originalSize:(UIImage*) image 
{ 
    return CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); 
} 
+ (UIImage *)decodedImageWithImage:(UIImage *)image { 
    return [self decodedImageWithImage:image maxSize:MAX_IMAGE_SIZE]; 
} 
+ (UIImage *)decodedImageWithImage:(UIImage *)image maxSize:(NSInteger) maxSize{ 
    if (image.images) { 
     // Do not decode animated images 
     return image; 
    } 

    CGImageRef imageRef = image.CGImage; 
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); 
    imageSize = [self checkMaxImageSize:imageSize maxSize:maxSize]; 
    CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize}; 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 

    int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask); 
    BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || 
         infoMask == kCGImageAlphaNoneSkipFirst || 
         infoMask == kCGImageAlphaNoneSkipLast); 

    // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB. 
    // https://developer.apple.com/library/mac/#qa/qa1037/_index.html 
    if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) { 
     // Unset the old alpha info. 
     bitmapInfo &= ~kCGBitmapAlphaInfoMask; 

     // Set noneSkipFirst. 
     bitmapInfo |= kCGImageAlphaNoneSkipFirst; 
    } 
    // Some PNGs tell us they have alpha but only 3 components. Odd. 
    else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) { 
     // Unset the old alpha info. 
     bitmapInfo &= ~kCGBitmapAlphaInfoMask; 
     bitmapInfo |= kCGImageAlphaPremultipliedFirst; 
    } 

    // It calculates the bytes-per-row based on the bitsPerComponent and width arguments. 
    CGContextRef context = CGBitmapContextCreate(NULL, 
               imageSize.width, 
               imageSize.height, 
               CGImageGetBitsPerComponent(imageRef), 
               0, 
               colorSpace, 
               bitmapInfo); 
    CGColorSpaceRelease(colorSpace); 

    // If failed, return undecompressed image 
    if (!context) return image; 

    CGContextDrawImage(context, imageRect, imageRef); 
    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); 

    CGContextRelease(context); 

    UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; 
    CGImageRelease(decompressedImageRef); 
    return decompressedImage; 
} 

+ (CGSize) checkMaxImageSize:(CGSize) size maxSize:(NSInteger) max 
{ 
    CGFloat whRatio = size.width/size.height; 
    if (size.height > max || size.width > max) { 
     if (size.height > size.width) { 
      size.width = max * whRatio; 
      size.height = max; 
     }else{ 
      size.width = max ; 
      size.height = max/whRatio; 
     } 
    } 
    return size; 
} 
+0

謝謝,會給它一個嘗試,但不是它仍然呈現圖像需要系統解碼並將其保存在內存中? – Iowa15

相關問題