0

画像フィルターを適用するために次のコードを使用しています。私のアプリでは、明るさ、コントラスト、彩度をフィルタリングしています。それぞれ 3 つの個別のスライダーを使用して値を変更しています。値を移動し続けると、メモリ消費量が 1.5 GB を超えてクラッシュします。クラッシュのない実装のためにこのメモリ消費を減らす方法はありますか?

(void)setBrightnessAndContrastOf:(UIImage *)image { // forTarget:(UIImageView *)imgView {

    if (!image) {
        return;
    }

    CIImage *inputImage = [[CIImage alloc] initWithImage:image];
    CIFilter *exposureAdjustmentFilter = [CIFilter filterWithName:@"CIColorControls"];
    [exposureAdjustmentFilter setDefaults];
    [exposureAdjustmentFilter setValue:inputImage forKey:@"inputImage"];

    [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:self.contrastValue] forKey:@"inputContrast"]; //default = 1.00
    [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:self.brightnessValue] forKey:@"inputBrightness"]; //default = 0.00
    [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:self.saturationValue] forKey:@"inputSaturation"]; //default = 1.00
    CIImage *outputImage = [exposureAdjustmentFilter valueForKey:@"outputImage"];

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef tempImage = [context createCGImage:outputImage fromRect:[outputImage extent]];

    UIImage *newImage = [UIImage imageWithCGImage:tempImage];

    [imageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:NO];
    CGImageRelease(tempImage);

    inputImage = nil;
    context = nil;
    outputImage = nil;
    exposureAdjustmentFilter = nil;
}
4

2 に答える 2

0

メインスレッド内で重い画像操作を行うことは想定されていません。マルチスレッドを実装していない限り (コード スニペットに記載されていません)、実装してください。

あなたは試すことができます:

dispatch_queue_t backgroundQueue = dispatch_queue_create("com.yourorg", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(backgroundQueue, ^
                   {
     // setBrightnessAndContrastOf method goes here

        dispatch_sync(mainQueue, ^ {

               //notify main thread about process status
                      });

          });

ARC を使用しているため、メモリの過剰消費によるクラッシュはほとんどありません。ただし、メイン スレッドを長時間ブロックすると、ウォッチドッグ タイマーがバックドアを介してメイン スレッドを取り出し、頭に撃ち込みます。

計測器を使用してヒープ サイズを監視し、根本的な原因を突き止めます。

于 2013-10-31T11:41:47.437 に答える
0

setImage メソッドが何をしているのかわかりませんが、 performSelector の前に CGImageRelease(tempImage) を移動します。

于 2013-10-31T11:57:09.950 に答える