1

タイミング プロファイル ツールを使用して、時間の 95% が関数 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();
}
4

1 に答える 1

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;
}

このようにして、リソース イメージのレンダリングされたコピーを取得します。レンダリング中はコンテキストがあるため、好きなことを自由に行うことができます。事前に出力サイズを決定する必要があります。

結果として得られるイメージは、後で使用するためにUIImage入れることができるの単なるインスタンスです。NSMutableDictionary

于 2012-03-31T11:22:51.707 に答える