Search code examples
iosobjective-cimagephasset

the memory of using drawInRect to resize picture


recently i use PHAssets replace the old Assets in my project.However,when i use my app to scale some pictures ,i found it usually crashes. i use the debug mode, found it is the memory problem. i use the code below to resize picture

  +(UIImage*)scaleRetangleToFitLen:(UIImage *)img sWidth:(float)wid sHeight:(float)hei{
    CGSize sb = img.size;;
    if (img.size.height/img.size.width > hei/wid) {
        sb = CGSizeMake(wid,wid*img.size.height/img.size.width);
    }else{
        sb = CGSizeMake(img.size.width*hei/img.size.height,hei);
    }
    if (sb.width > img.size.width || sb.height > img.size.height) {
        sb = img.size;
    }
    UIImage* scaledImage = nil;
    UIGraphicsBeginImageContext(sb);
    [img drawInRect:CGRectMake(0,0, sb.width, sb.height)];
    scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    img = nil;
    return scaledImage;
}

the memory will increase about 50M when the code

 [img drawInRect:CGRectMake(0,0, sb.width, sb.height)] 

runs and it will not be setted free even thought the method is finished. the width and the height is 304*228 ,the image original size is about 3264*2448,the returned image is 304*228;it means the real image i wanted at last is just a 304*228 size image,however it takes 50+M memory.. Is there any way to free the memory the drawInRect: function takes? (the @autoreleasepool does not work ~ 😢 😢)


Solution

  • When loading an image, iOS usually doesn't decompress it until it really needs to. So the image you pass into your function is most likely a JPEG or PNG image that iOS keeps in memory in it's compressed state. The moment you draw it, it will be decompressed first and therefore the memory increases significantly. I would expect an increase by 3264 x 2448 x 4 = 35MB (and not 50MB).

    To get rid of the memory again, you will make sure you release all reference to the image you pass into your function. So the problem is outside the code you show in your question.

    For a more specific answer, you'll need to show all the code that works with the original image.