

UIImageをリサイズするメソッドを作りました。画像の配列の要素を取り出して1つ1つリサイズしていく処理を書いた時に、メモリが上手く開放されず高画質な画像が何度もリサイズされるとメモリが足りなくなってしまいます。ARC環境で以下のようなコードを書きたい場合はどのようにメモリを開放するべきなのでしょうか？

「trimmedImage」が開放されていないようなので、trimmedImageを強制的に開放する手段がございましたらどなたかご教授願います。(※@autoreleasepoolの利用や、trimmedImage
= nil;などもやってみましたが次のループまでに開放されておらず、総使用メモリが増えるのみでした。)

[code]

    + (void)cropImages: (NSArray *)images {
        for (__weak UIImage *image in images) {
            UIImage *resizedImage = [self cropRectImage:image];
        }
    }
    
    
    + (UIImage *)cropRectImage: (UIImage *)image {
        float w = image.size.width;
        float h = image.size.height;
        CGRect rect;
    
        if (h <= w) {
            float x = w / 2 - h / 2;
            float y = 0;
            rect = CGRectMake(x, y, h, h);
        }else {
            float x = 0;
            float y = h / 2 - w / 2;
            rect = CGRectMake(x, y, w, w);
        }
    
        CGImageRef cgImage = CGImageCreateWithImageInRect(image.CGImage, rect);
        UIImage *trimmedImage = [UIImage imageWithCGImage:cgImage];
    
        CGSize newSize = CGSizeMake(320, 320);
        UIGraphicsBeginImageContext(newSize);
        UIImage *resizedImage = nil;
        [trimmedImage drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        // TODO: ここでAutoReleaseされるはずだが... (http://vladimir.zardina.org/2010/05/resizing-uiimage-objects/)
        resizedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        image = nil;
        cgImage = nil;
    
        return resizedImage;
    }
    
[/code]


CC BY-SA 3.0
2015-12-12T18:04:47.947
19924
2015-12-13T10:23:18.247
3983
question
ios objective-c xcode
UIImageのリサイズでdrawInRectをfor文で回した時のメモリ解放タイミングについて


原因としてはすでにコメントで解決されているように`CGImageRef`の解放漏れです。

このケースだとトリミングとリサイズで2手使って描画していますが、トリミングのための画像サイズが大きく、加えて`CGImageRef`ですので明示的に解放しなければならないのですが、リサイズの時に負の方向にoriginを設定すれば1手で済み、ARC環境内の話になるので簡単かと思います。

[code]

    + (UIImage *)cropRectImage: (UIImage *)image {
        CGFloat w = image.size.width, h = image.size.height;
        float scale = (h < w) ? 320 / h : 320 / w;
        CGSize size = CGSizeMake(w * scale, h * scale);
    
        UIGraphicsBeginImageContext(CGSizeMake(320, 320));
        [image drawInRect:CGRectMake((320 - size.width) / 2, (320 - size.height) / 2, size.width, size.height)];
        UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return resizedImage;
    }
    
[/code]


CC BY-SA 3.0
2015-12-13T10:23:18.247
19936
2015-12-13T10:23:18.247
5337
19924
answer