2009-06-25 18 views
3

私はiPhoneアプリ開発の新人ですので、間違ったことをしている可能性があります。複数の画像操作クラッシュiPhoneアプリケーション

基本的には、インターネットから複数の画像をロードして、それらを切り取っています。イメージを非同期にロードしてビューに追加する例を見つけることができました。私はに追加されたNSOperationを通してNSDataの画像を追加することでそれを達成しました。その後

、私は固定サイズの親指をしなければならなかったので、私はこの画像をトリミングする方法が必要なので、私は重要でないと一緒に、基本的にトリミングされた画像を描画するUIGraphicsBeginImageContext()UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()を使用して、ネット上でスクリプトを見つけましたサイズ計算。

方法は機能しますが、この画像の20個のように生成されているので、それらのいくつかが生成された後、または時折、アプリケーションを1〜2回閉じてからもう一度開いた後にランダムにクラッシュします。

この場合、どうすればよいですか?私はこのメソッドを何とか非同期で実行するようにしましたが、NSOperationsNSOperationQueueで運がありません。

作物のコードは、私が思う以上に関連している場合は、ここにある:

UIGraphicsBeginImageContext(CGSizeMake(50, 50)); 
CGRect thumbnailRect = CGRectZero; 
thumbnailRect.origin = CGPointMake(0.0,0.0); //this is actually generated 
              // based on the sourceImage size 
thumbnailRect.size.width = 50; 
thumbnailRect.size.height = 50; 
[sourceImage drawInRect:thumbnailRect]; 
newImage = UIGraphicsGetImageFromCurrentImageContext(); 

ありがとう!

+0

クラッシュが発生したときのデバッガの動作を教えてください。また、これはデバイス上またはシミュレータ上で実行されていますか? – zpesk

+0

NSOperationQueueではなく、同期して作業するだけでクラッシュしますか?不思議なクラッシュの通常の理由は、リリースしてはいけないものをリリースしていることです。特に、スタックトレースで「autorelease」または「pool」という単語がある場合は... –

答えて

5

画像を拡大/縮小するコードがあまりにも単純すぎます。 ここに私が使用しているものがあります。ご覧のように、漏れはなく、不要になったときにオブジェクトが解放されます。お役に立てれば。それがない

// Draw the image into a pixelsWide x pixelsHigh bitmap and use that bitmap to 
// create a new UIImage 
- (UIImage *) createImage: (CGImageRef) image width: (int) pixelWidth height: (int) pixelHeight 
{ 
    // Set the size of the output image 
    CGRect aRect = CGRectMake(0.0f, 0.0f, pixelWidth, pixelHeight); 
    // Create a bitmap context to store the new thumbnail 
    CGContextRef context = MyCreateBitmapContext(pixelWidth, pixelHeight); 
    // Clear the context and draw the image into the rectangle 
    CGContextClearRect(context, aRect); 
    CGContextDrawImage(context, aRect, image); 
    // Return a UIImage populated with the new resized image 
    CGImageRef myRef = CGBitmapContextCreateImage (context); 

    UIImage *img = [UIImage imageWithCGImage:myRef]; 

    free(CGBitmapContextGetData(context)); 
    CGContextRelease(context); 
    CGImageRelease(myRef); 

    return img; 
} 


// MyCreateBitmapContext: Source based on Apple Sample Code 
CGContextRef MyCreateBitmapContext (int pixelsWide, 
            int pixelsHigh) 
{ 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

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

    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    bitmapData = malloc(bitmapByteCount); 
    if (bitmapData == NULL) 
    { 
     fprintf (stderr, "Memory not allocated!"); 
     CGColorSpaceRelease(colorSpace); 
     return NULL; 
    } 
    context = CGBitmapContextCreate (bitmapData, 
            pixelsWide, 
            pixelsHigh, 
            8, 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaPremultipliedLast); 
    if (context== NULL) 
    { 
     free (bitmapData); 
     CGColorSpaceRelease(colorSpace); 
     fprintf (stderr, "Context not created!"); 
     return NULL; 
    } 
    CGColorSpaceRelease(colorSpace); 

    return context; 
} 
+0

こんにちはしかし私はまだこの問題を抱えているので、あなたの答えを見直すことにしました。私はあなたのコードを使用しようとしていますが、私はUIImageとして画像を持っており、あなたの関数はCGImageRefを必要とします。また、このスクリプトはイメージの縮尺を変更するだけです。私もそれを切り刻む必要があります。 – treznik

+0

後継のために、 'UIImage'はそのイメージの' CGImageRef'を与えるプロパティ 'CGImage'を定義します。 –

0

は疑いメモリクラッシュのうちのように聞こえます。 Leaksツールを起動し、メモリ全体の傾向を確認してください。

2

使用している呼び出し(たとえば、UIGraphicsBeginImageContext)がメインスレッドからのみ安全に行うことができるUIKitのコンテキストスタックを操作するため、アプリがクラッシュしています。

unforgivenのソリューションは、コンテキストスタックを操作しないため、スレッドで使用するとクラッシュしません。

+0

それは理にかなっています。事実として、私はこれを疑っていましたが、私はunforgivenのソリューションを使用しようとしましたが、CGImageRefを期待し、外部イメージをUIImageにロードしているので、彼の関数の使い方はわかりません。あなたは私のためにこれをクリアすることができると思いますか?ありがとう。 – treznik

+0

これは8年後のことですが、UIGraphicsBeginImageContextはスレッドセーフです。 – Oded

関連する問題