6

大きなPNG画像の束をピクセルごとに解析する必要がある方法があります(PNGはそれぞれ600x600ピクセルです)。Simulator では問題なく動作するようですが、デバイス (iPad) では、一部の内部メモリ コピー関数で EXC_BAD_ACCESS が発生します。小さい画像で試してみると、すべてがうまくいくように見えるので、サイズが原因のようです。これは、以下のメソッドのメモリ関連の肉です。

+ (CGRect) getAlphaBoundsForUImage: (UIImage*) image 
{    
    CGImageRef imageRef = [image CGImage];

NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

unsigned char *rawData = malloc(height * width * 4);
memset(rawData,0,height * width * 4);

NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);

/* non-memory related stuff */

free(rawData);

これを一連の画像で実行すると、12回実行されてから失敗しますが、シミュレーターでは問題なく実行されます。何かアイデアはありますか?

4

8 に答える 8

3

12回実行してからクラッシュすると、メモリ不足の問題のように聞こえます。内部的には、CGContextがいくつかの大きな自動解放された構造を作成している可能性があります。これをループで実行しているため、それらは解放されないため、メモリが不足して死んでしまいます。

ただし、CoreFoundationが一時オブジェクトをどのように処理するかはわかりません。CFオブジェクトには自動リリースに相当するものはないと思います。コアグラフィックスコンテキストは、NSObjectではなくCFオブジェクトをほぼ確実に処理します。

コードのメモリチャーンを減らすために、処理を開始する前に一度リファクタリングしてオフスクリーンCGContextを作成し、それを繰り返し使用して各画像を処理することをお勧めします。終わったら放します。いずれの場合も、これはより高速になります(ループを通過するたびに巨大なデータ構造を割り当てないため)。

クラッシュの問題を解消するために賭けます。また、コードがはるかに高速になると思います。メモリの割り当ては他の操作に比べて非常に遅く、600x600ピクセルのRGBA画像を処理するためにかなり大きなデータ構造を使用しています。

于 2012-02-26T02:33:41.870 に答える
3

製品に移動 -> スキームの編集 -> ゾンビ オブジェクトを有効にします。Enable Zombie オブジェクトの前にチェック マークを付けます。ビルドして実行します。これにより、EXC_BAD_ACCES エラーのより適切な説明が得られます。

于 2012-06-11T15:09:40.023 に答える
0

おそらくCGImageGetBytesPerRow(2の累乗は過剰に聞こえます)。

于 2010-04-14T00:08:19.097 に答える
0

正方形のコンテキスト(幅=高さ)を作成することで問題を解決しました。512x256のテクスチャがあり、OpenGLにデータを送信するたびにクラッシュしていました。ここで、512x512のバッファーを割り当てますが、それでも512x256をレンダリングします。お役に立てれば。

于 2012-12-30T21:21:04.950 に答える
0

プログラムで画像を作成していたため、行サイズを直接定義するアプリで 2 のべき乗の整列された行サイズを使用しました。しかし、私の提案を試す前に toastie に CGImageGetBytesPerRow を試すこともお勧めします。

于 2010-04-14T07:04:32.933 に答える
0

たぶん交換

CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGColorSpaceRelease(colorSpace);

色空間参照がまだ何らかの形で必要になる可能性があるためですか?単なるランダムな推測です...そして、コンテキストのリリースの背後に置くことさえありますか?

// cleanup
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
于 2012-06-11T23:46:16.323 に答える
0

CGImageCreate() を使用して、iPad (もちろん iPhoneOS 3.2) で同様のクラッシュが発生していました。あなたの苦労を見てヒントになりました。bytesPerRow を次に大きい 2 の累乗に合わせることで問題を解決しました。

size_t bytesPerRowPower2 = (size_t) round( pow( 2.0, trunc( log((double) bytesPerRow) / log(2.0) ) + 1.0 ) );

2 列の累乗を提供することで問題が解決するかどうかをお知らせください。調整されたサイズで *rawData を割り当て、bytesPerRowPower2 を CGBitmapContextCreate() に渡す必要があります...高さの位置合わせは必要ないようです。

于 2010-04-13T07:32:27.503 に答える
0

デバイスでアプリケーションを実行しているときにインストゥルメントの割り当てを実行してみてください。これはメモリ関連の問題です。ループに陥っている場合は、そのループ内に自動解放プールを作成します。

于 2012-03-19T06:18:50.143 に答える