Ошибка NSInvalidArgument — CGImageRef из CIImage

Я получаю сообщение об ошибке в каком-то коде, который два дня назад работал нормально. Ошибка:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType extent]: unrecognized selector sent to instance 0x1bc8f0'

он указывает на эту строку на main.m:

return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

Используя журналы, чтобы увидеть, куда попадает мой код, кажется, что эта строка выдает ошибку:

greySave = [context createCGImage:greyscaleImage fromRect:[greyscaleImage extent]];

greySave — это CGImageRef, объявленный в начале моего контроллера представления. Достаточно просто взять вывод CIImage и преобразовать его в CGImageRef для сохранения:

desaturate = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues:kCIInputImageKey, colourSave, @"inputIntensity", [NSNumber numberWithFloat:0.00], nil];


greyscaleImage = [desaturate valueForKey:@"outputImage"];


greySave = [context createCGImage:greyscaleImage fromRect:[greyscaleImage extent]];

Единственное, что я изменил, что, как я думаю (хотя и не понимаю, почему) может вызвать проблему, — это добавление дополнительного условного оператора, который будет применять второй фильтр, если пользователь хочет это сделать:

if ([_alphaButtonSavedState isEqualToString:@"ON"]) {
             NSLog(@"user does want alpha on greyscale");
            //user wants alpha mask also  
        } else {
             NSLog(@"user does not want alpha on greyscale");
            //convert to CGImage for saving
            greySave = [context createCGImage:greyscaleImage fromRect:[greyscaleImage extent]];
             NSLog(@"greySave cgimage created");

            //save the grey image
            [library writeImageToSavedPhotosAlbum:greySave metadata:[greyscaleImage properties] completionBlock:^(NSURL *assetURL, NSError *error){
                if (error) {
                    NSLog(@"ERROR in greyscale save: %@", error);
                } else
                {
                    NSLog(@"SUCCESS in greyscale save");
                    //in here we'll put a nice animation or something
                    //CGImageRelease(greyscaleImage);
                }
            }];

Есть идеи, почему это происходит?

Спасибо.

РЕДАКТИРОВАТЬ:

Вот весь кусок кода, на всякий случай, если это поможет.

[stillImage captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) {

    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];  //get the raw image data from the session
    UIImage *startImage = [[UIImage alloc] initWithData:imageData];  //create a UIImage from that image data, let's us work with it

    //resizing of image to take place before anything else
    UIImage *image = [UIImage imageWithImage:startImage scaledToSize:_exportSSize];  //scale the image so it's shortest side is the size given in prefs

    NSLog(@"image width post scale: %g", image.size.width);
    NSLog(@"image height post scale is: %g", image.size.height);

    //change the context to render using cpu, so on app exit renders get completed
    context = [CIContext contextWithOptions: [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:kCIContextUseSoftwareRenderer]];

    //new crop testing - not using CIImage - seems to work, just need to sort out crop region
    CGRect cropRect = CGRectMake(0, 0, _exportSize, _exportSize);
    UIImage *cropper = [self imageByCropping:image toRect:cropRect];

    //the colour image is always saved so create a CGImage to save later
    colourSave = [cropper CGImage];
    NSLog(@"coloursave image created");

    //now we convert and create CGImages based upon chosen export options
    if ([_greyButtonSavedState isEqualToString:@"ON"]) {
        NSLog(@"inside the greyscale conditional");
        //user wants greyscale image
        //create a CIMonochrome filter 
        desaturate = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues:kCIInputImageKey, colourSave, @"inputIntensity", [NSNumber numberWithFloat:0.00], nil];
         NSLog(@"desat ci filter created");
        //get the output
        greyscaleImage = [desaturate valueForKey:@"outputImage"];
         NSLog(@"dest output image created");

        //if the user wants to add the alpha
        if ([_alphaButtonSavedState isEqualToString:@"ON"]) {
             NSLog(@"user does want alpha on greyscale");
            //user wants alpha mask also  
        } else {
             NSLog(@"user does not want alpha on greyscale");
            //convert to CGImage for saving
            greySave = [context createCGImage:greyscaleImage fromRect:[greyscaleImage extent]];
             NSLog(@"greySave cgimage created");

            //save the grey image
            [library writeImageToSavedPhotosAlbum:greySave metadata:[greyscaleImage properties] completionBlock:^(NSURL *assetURL, NSError *error){
                if (error) {
                    NSLog(@"ERROR in greyscale save: %@", error);
                } else
                {
                    NSLog(@"SUCCESS in greyscale save");
                    //in here we'll put a nice animation or something
                }
            }];
        }
    }

-- здесь еще два условных оператора, оба пока пустые

-- с последующим сохранением изображения colorSave, это работает нормально.

-- тогда метод заканчивается.

Еще одна вещь, вот как я обрезаю изображение. Возвращаемое изображение из следующего метода — это то, из чего я создаю CIImage:

-(UIImage *)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect

{ CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);

UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

return cropped;

}


person mrEmpty    schedule 12.05.2012    source источник
comment
Если это поможет, входным изображением для CIFilter будет UIImage.   -  person mrEmpty    schedule 12.05.2012
comment
Можете ли вы поставить точку останова на строку, где вы создаете CGImage, и посмотреть, что установлено для greyscaleImage? Ошибка говорит о том, что объект greyscaleImage не реализует метод -extent. Может ли greyscaleImage быть nil или объектом другого типа?   -  person user1118321    schedule 12.05.2012
comment
@user1118321 user1118321 Логически, greyscaleImage — это CGImage, потому что он наследуется от NSCFType. Это не nil, потому что тогда бы не произошел сбой, поскольку сообщения nil производят nil.   -  person CodaFi    schedule 12.05.2012
comment
Я создаю greyscaleImage как CIImage: CIImage *greyscaleImage; Как я уже сказал, эта ошибка не возникала раньше, используя тот же метод для преобразования и сохранения. Цветное изображение сохраняется. Я опубликую весь фрагмент кода, так как это может помочь.   -  person mrEmpty    schedule 12.05.2012
comment
Условие не имеет значения, поэтому мне интересно, имеет ли оно какое-либо отношение к методу, который я использую для кадрирования изображения, показанного здесь: -(UIImage *)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect { CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], прямоугольник); UIImage *cropped = [UIImage imageWithCGImage:imageRef]; CGImageRelease (изображениеСсылка); возврат обрезанный; }   -  person mrEmpty    schedule 12.05.2012
comment
Если я попытаюсь зарегистрировать экстент, он выдаст ту же ошибку: greyscaleImage = [desaturate outputImage]; //получить выходной NSLog(@dest output image created); NSLog(@greyscaleImage ширина: %f, greyscaleImage.extent.size.width); NSLog(@greyscaleImage height: %f, greyscaleImage.extent.size.height);   -  person mrEmpty    schedule 12.05.2012
comment
@ user1118321 указал мне правильное направление, не было никакой степени, потому что я загружал CGImage в CIFilter вместо CIImage. Никаких ошибок не было, так что я не заметил это сразу. Сейчас я загружаю CIImage в фильтр и преобразовываю экспорт, и все хорошо. Теперь я могу закончить свое приложение :) Просто нужно протестировать тест-тест и настроить, настроить, настроить. :)   -  person mrEmpty    schedule 12.05.2012


Ответы (1)


Добавление ответа на случай, если это поможет кому-то еще.

Я передавал UIImage в CIFilter, это вызывало проблему. Преобразование UIImage в CIImage и его передача решили проблему.

person mrEmpty    schedule 13.05.2012