2012-03-31 1 views
1

시간 프로필 도구를 사용하여 CGContextDrawImage 함수를 호출하는 데 소요 된 시간이 95 %임을 확인했습니다.iOS - CGContextDrawImage를 캐시 할 수 있습니까?

내 앱에는 반복적으로 스프라이트 맵에서 잘리고 화면에 그려지는 많은 중복 이미지가 있습니다. CGFormextDrawImage의 출력을 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의 인스턴스입니다.