2016-07-01 5 views
2

У меня массивный UIImage, загруженный с веб-ресурса (> 300 МБ), который при попытке визуализации вызывает сбои приложения из-за памяти. Я пытаюсь изменить размер изображения, используя следующий код:Изменение размера 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

Проблема заключается в том, что вы держите в руках изображение в памяти. Загрузите его на диск и используйте среду ImageIO для чтения «миниатюры» (меньшего размера) прямо с диска без необходимости хранить полноразмерный образ в памяти.

+0

Спасибо, это сработало для меня и спасло мне головную боль! – Iowa15

0

Вы можете попробовать это один + (UIImage *)decodedImageWithImage:(UIImage *)image maxSize:(NSInteger) maxSize. код из 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

Смежные вопросы