2012-03-31 9 views
1

タイミングプロファイルツールを使用して、時間の95%が関数CGContextDrawImageを呼び出すのに費やされたことを確認しました。iOS - CGContextDrawImageをキャッシュできますか?

私のアプリでは、スプライトマップから重複して重複した画像が繰り返し表示され、画面に描画されます。 CGContextDrawImageの出力をNSMutableDictionayにキャッシュすることが可能かどうか疑問に思っていました。同じスプライトが再び要求された場合は、クリッピングと再描画の作業をすべて行うのではなく、キャッシュから引き出します。これは私が持っているものですが、私は成功していない:

定義

if(cache == NULL) cache = [[NSMutableDictionary alloc]init]; 
//Identifier based on the name of the sprite and location within the sprite. 
NSString* identifier = [NSString stringWithFormat:@"%@-%d",filename,frame]; 

あり、キャッシュされたスプライト レンダリングキャッシュに

CGRect clippedRect = CGRectMake(0, 0, clipRect.size.width, clipRect.size.height); 
    CGContextClipToRect(context, clippedRect); 

    //create a rect equivalent to the full size of the image 
    //offset the rect by the X and Y we want to start the crop 
    //from in order to cut off anything before them 
    CGRect drawRect = CGRectMake(clipRect.origin.x * -1, 
           clipRect.origin.y * -1, 
           atlas.size.width, 
           atlas.size.height); 

    //draw the image to our clipped context using our offset rect 
    CGContextDrawImage(context, drawRect, atlas.CGImage); 
    [cache setValue:UIGraphicsGetImageFromCurrentImageContext() forKey:identifier]; 
    UIGraphicsEndImageContext(); 

を追加しますおそらく私の究極のキャッシング目標であるCGImageをレンダリングするより良い方法ですが、現時点ではちょっと見ていますキャッシュされたイメージを正常にレンダリングしますが、これは成功しませんでした。

UIImage* cachedImage = [cache objectForKey:identifier]; 

if(cachedImage){ 
    NSLog(@"Cached %@",identifier); 

    CGRect imageRect = CGRectMake(0, 
            0, 
            cachedImage.size.width, 
            cachedImage.size.height); 

    if (NULL != UIGraphicsBeginImageContextWithOptions) 
     UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0); 
    else 
     UIGraphicsBeginImageContext(imageRect.size); 

    //Use draw for now just to see if the image renders out ok 
    CGContextDrawImage(context, imageRect, cachedImage.CGImage); 
    UIGraphicsEndImageContext(); 
} 

答えて

3

はい、レンダリングされたイメージをキャッシュすることは可能です。以下は、それがどのように行われたかのサンプルです:

+ (UIImage *)getRenderedImage:(UIImage *)image targetSize:(CGSize)targetSize 
{ 
    CGRect targetRect = CGRectIntegral(CGRectMake(0, 0, targetSize.width, targetSize.height)); // should be used by your drawing code 
    CGImageRef imageRef = image.CGImage; // should be used by your drawing code 
    UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    // TODO: draw and clip your image here onto context 
    // CGContextDrawImage CGContextClipToRect calls 
    CGImageRef newImageRef = CGBitmapContextCreateImage(context); 
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; 
    CGImageRelease(newImageRef); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 

このようにして、リソースイメージのレンダリングされたコピーを取得します。レンダリング中はコンテキストがあるので、自由に何でもできます。あらかじめ出力サイズを決定するだけで済みます。

結果イメージは、後で使用するためにNSMutableDictionaryに入れることができるUIImageのインスタンスに過ぎません。

関連する問題