2012-05-29 14 views
6

2つのUIImageを1つのコンテキストにマージしています。それは動作しますが、それはかなり遅く実行され、私はより高速なソリューションが必要です。私の解決策として、iPad 1GでmergeImage: withImage:を呼び出すには約400msかかります。ここでCGContextDrawImageよりも速く2つのUIImageをマージする

は、私が何をすべきかです:

-(CGContextRef)mergeImage:(UIImage*)img1 withImage:(UIImage*)img2 
{ 
    CGSize size = [ImageToolbox getScreenSize]; 
    CGContextRef context = [ImageToolbox createARGBBitmapContextFromImageSize:CGSizeMake(size.width, size.height)]; 

    CGContextSetRenderingIntent(context, kCGRenderingIntentSaturation); 

    CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), img1.CGImage); 
    CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), img2.CGImage); 


    return context; 
} 

そしてここImageToolboxクラスから静的メソッドです:パフォーマンスを向上させる

static CGRect screenRect; 

+ (CGContextRef)createARGBBitmapContextFromImageSize:(CGSize)imageSize 
{ 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

    size_t pixelsWide = imageSize.width; 
    size_t pixelsHigh = imageSize.height; 

    bitmapBytesPerRow = (pixelsWide * 4); 
    bitmapByteCount  = (bitmapBytesPerRow * pixelsHigh); 

    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    if (colorSpace == NULL) 
    { 
     fprintf(stderr, "Error allocating color space\n"); 
     return NULL; 
    } 

    bitmapData = malloc(bitmapByteCount); 
    if (bitmapData == NULL) 
    { 
     fprintf (stderr, "Memory not allocated!"); 
     CGColorSpaceRelease(colorSpace); 
     return NULL; 
    } 

    context = CGBitmapContextCreate (bitmapData, 
            pixelsWide, 
            pixelsHigh, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaPremultipliedFirst); 
    if (context == NULL) 
    { 
     free (bitmapData); 
     fprintf (stderr, "Context not created!"); 
    } 

    CGColorSpaceRelease(colorSpace); 

    return context; 
} 

+(CGSize)getScreenSize 
{ 
    if (screenRect.size.width == 0 && screenRect.size.height == 0) 
    { 
     screenRect = [[UIScreen mainScreen] bounds];  

    } 
    return CGSizeMake(screenRect.size.height, screenRect.size.width-20); 
} 

任意の提案ですか?

+0

それぞれの方法がどれくらい時間がかかりますか? – EmilioPelaez

+0

drawImageの呼び出しには約400msかかり、残りのメソッドはそれぞれ10ms以下です。 –

+0

あらかじめ組み合わせてお使いのアプリに同梱されている画像はありますか?パフォーマンスのヒットは、色空間のコンボとアルファの事前乗算のために発生する可能性が最も高いです。それらを少しでも遊んでください。 –

答えて

0

私は画像をより速くマージする方法を見つけることができませんでした。私は操作をより速くするために画像のサイズを縮小しました。

0

私は間違いなく、どのメッセージが最も時間を費やしているかをプロファイルするためにInstrumentsを使用することをお勧めします。また、コードを少なくして同じことをしなければならないと思うカップルの方法を書いたことがありますが、実際にカスタマイズできるようにすべての方法を書かなければなりません。ここで彼らはとにかく、次のとおりです。

-(CGContextRef)mergeImage:(UIImage *)img1 withImage:(UIImage *)img2 
{ 
    CGSize size = [ImageToolbox getScreenSize]; 
    CGRect rect = CGRectMake(0, 0, size.width, size.height); 

    UIGraphicsBeginImageContextWithOptions(size, YES, 1.0); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSetRenderingIntent(context, kCGRenderingIntentSaturation); 

    [img1 drawInRect:rect]; 
    [img2 drawInRect:rect]; 

    UIGraphicsEndImageContext(); 

    return context; 
} 

それとも、すぐに合成画像を望んでいた場合:

- (UIImage *)mergeImage:(UIImage *)img1 withImage:(UIImage *)img2 
{ 
    CGSize size = [ImageToolbox getScreenSize]; 
    CGRect rect = CGRectMake(0, 0, size.width, size.height); 

    UIGraphicsBeginImageContextWithOptions(size, YES, 1.0); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSetRenderingIntent(context, kCGRenderingIntentSaturation); 

    [img1 drawInRect:rect]; 
    [img2 drawInRect:rect]; 

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return image; 
} 

彼らは速いかないだろう場合、私はわかりませんが、私は実際にどのように知ることはできませんあなたが楽器のプロフィールを分解しない限り、あなたが非常に簡単にできるスピードアップ。

いずれにしても、これが役立つことを願っています。

+0

私はちょうど私の方法であらゆる種類の愚かな記憶問題があるかもしれないことに気づいたが、それらは単純な修正である。必要に応じて、または必要でない場合は、簡単にコンテキストを保持できます。しかし、あなたはその考えを得る。 – Ben

+0

あなたのソリューションはCGContextDrawImage呼び出しなしでは動作しません。 drawInRectの呼び出しの後にCGContextDrawImageを作成する必要があります。しかし、私はメソッドの実行時間を得ることができました。drawInRectは400msかかるので、img_decode_stageでは200ms、img_interpolate_readでは200msで終了します。 –

+0

ああ、あなたdrawInRectの代わりに簡単に使用することができます。ちょうど、コードではあまり良くないとは限らないことを示しています。明らかにどのソリューションにおいても、最も長い時間を要するメッセージは実際の描画メッセージです。もしあなたが本当にパフォーマンスを圧迫したいのであれば、あなたはニッチ・ピカイを取得しなければならないでしょう。例えば:CGRectMakeを使う代わりに、varで一度使ってみて、再利用します。なぜなら、おそらく問題ではないような少しの構造体を使っても、男性の割り当てはやや面倒ですからです。コンテキストを割り当てるときは、新しいCGSizeを割り当てる代わりに、varサイズを使用します。 – Ben

関連する問題