iPhone CGContextRef CGBitmapContext Создать неподдерживаемую комбинацию параметров

В моем приложении мне нужно изменить размер и обрезать некоторые изображения, хранящиеся локально и онлайн. Я использую учебник Тревора Хармона, который реализует UIImage+Resize,

На моем iPhone 4(iOS 4.3.1) все работает нормально, у меня нет проблем. Но на моем iPhone 3G (iOS 3.2) методы изменения размера и обрезки не работают для любого изображения (локально сохраненные являются PNG). Это вывод консоли:

Tue Apr  5 02:34:44 Andreis-MacBook-Pro.local Puzzle[12453] <Error>: CGBitmapContextCreate:     unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 288 bytes/row.
Tue Apr  5 02:34:44 Andreis-MacBook-Pro.local Puzzle[12453] <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 288 bytes/row.
Tue Apr  5 02:34:44 Andreis-MacBook-Pro.local Puzzle[12453] <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 288 bytes/row.
Tue Apr  5 02:34:44 Andreis-MacBook-Pro.local Puzzle[12453] <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 288 bytes/row.

Это метод обрезки

- (UIImage *)croppedImage:(CGRect)bounds 
{
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return croppedImage;
}

Метод изменения размера:

- (UIImage *)resizedImage:(CGSize)newSize
            transform:(CGAffineTransform)transform
       drawTransposed:(BOOL)transpose
 interpolationQuality:(CGInterpolationQuality)quality 
{
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
    CGImageRef imageRef = self.CGImage;

    CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            0,
                                            CGImageGetColorSpace(imageRef),
                                            CGImageGetBitmapInfo(imageRef));
    if(bitmap == nil)
        return nil;

    CGContextConcatCTM(bitmap, transform);

    CGContextSetInterpolationQuality(bitmap, quality);

    CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);

    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    CGContextRelease(bitmap);
    CGImageRelease(newImageRef);

    return newImage;
}

Может кто-нибудь объяснить мне, как у меня эта проблема?

Спасибо Андрей

5 ответов

Отвечаю здесь, поскольку у меня был точно такой же формат пикселей, когда я получил эту ошибку. Надеюсь, этот ответ кому-нибудь поможет.

Причина, по которой это не удалось, в моем случае, заключалась в том, что kCGImageAlphaLast больше не разрешено в iOS 8, хотя оно хорошо работает в iOS 7. Комбинация 32 pbb, 8 bpc позволяет kCGImageAlphaNoneSkip* а также kCGImageAlphaPremultiplied* для Альфа-Инфо. По-видимому, это всегда было проблемой, но не было реализовано до iOS 8. Вот мое решение:

- (CGBitmapInfo)normalizeBitmapInfo:(CGBitmapInfo)oldBitmapInfo {
    //extract the alpha info by resetting everything else
    CGImageAlphaInfo alphaInfo = oldBitmapInfo & kCGBitmapAlphaInfoMask;

    //Since iOS8 it's not allowed anymore to create contexts with unmultiplied Alpha info
    if (alphaInfo == kCGImageAlphaLast) {
        alphaInfo = kCGImageAlphaPremultipliedLast;
    }
    if (alphaInfo == kCGImageAlphaFirst) {
        alphaInfo = kCGImageAlphaPremultipliedFirst;
    }

    //reset the bits
    CGBitmapInfo newBitmapInfo = oldBitmapInfo & ~kCGBitmapAlphaInfoMask;

    //set the bits to the new alphaInfo
    newBitmapInfo |= alphaInfo;

    return newBitmapInfo;
}

В моем случае ошибочный фрагмент кода выглядел следующим образом, где imageRef - это CGImageRef PNG, загруженного из пакета приложения:

CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                                newRect.size.width,
                                                newRect.size.height,
                                                CGImageGetBitsPerComponent(imageRef),
                                                0,
                                                CGImageGetColorSpace(imageRef),
                                                CGImageGetBitmapInfo(imageRef));

Источники: /questions/20363210/cgbitmapcontextcreate-nepodderzhivaemaya-kombinatsiya-parametrov/20363216#20363216

https://developer.apple.com/library/mac/DOCUMENTATION/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html

Я понял, что это проблема с цветовым пространством. Просто замените CGImageGetColorSpace(imageRef) на CGColorSpaceCreateDeviceRGB() . Это работает для меня при попытке сохранить изображение, которое я получил от AVCaptureSession. И не забудь выпустить его!

CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            0,
                                            rgbColorSpace,//CGImageGetColorSpace(imageRef), sometimes contains unsupported colorspace
                                            bitmapInfo);
CGColorSpaceRelease(rgbColorSpace);

У меня была та же проблема с симулятором iOS 5, и приведенные выше ответы не решили мою проблему: изображения не были загружены, и консоль все еще сообщала о тех же ошибках.

Я использую очень популярные категории, найденные здесь.

В этом блоге люди сталкиваются с одинаковыми проблемами. Ответ Мэтта от 22 ноября 2011 года помог мне.

Ура!

Хорошо, это может или не может помочь вам (и я ценю, что это старый пост)

Я получил подобную проблему, потому что параметр ширины (в вашем случае newRect.size.width) имел компонент десятичной дроби (например, 100,001 вместо 100,0). Я приведу его к целому числу и обратно, обрезая десятичный компонент, и проблема исчезла. я предполагаю, что есть тест, чтобы увидеть, что количество бит на компонент x пикселей и т. д. складывается, и это не может иметь дело с дробными пикселями / точками. Вы можете использовать этот метод, если он помогает.

+(CGSize)  fixSize:(CGSize) forSize{
    NSInteger w = (NSInteger) forSize.width;
    NSInteger h = (NSInteger) forSize.height;
    return CGSizeMake(w, h);
}

Я видел эту проблему в симуляторе при переключении с 5.1 на 6.1 для тестирования. Закрытие симулятора и его повторное открытие, похоже, устранили ошибку.

Другие вопросы по тегам