iPhone CGContextRef CGBitmapContextСоздать неподдерживаемую комбинацию параметров - PullRequest
10 голосов
/ 05 апреля 2011

В моем приложении мне нужно изменить размер и обрезать некоторые изображения, хранящиеся локально и онлайн.Я использую учебник Тревора Хармона , который реализует 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 ]

23 голосов
/ 14 октября 2014

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

Причина, по которой он не удался, в моем случае заключалась в том, что kCGImageAlphaLast больше не является допустимым значением в iOS 8, хотя хорошо работает в iOS 7. 32 pbb, Комбинация 8 бит на канал позволяет только 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));

Источники: https://stackoverflow.com/a/19345325/3099609

https://developer.apple.com/library/mac/DOCUMENTATION/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html#//apple_ref/doc/uid/TP30001066-CH203-BCIBHHBB

5 голосов
/ 10 декабря 2011

Я понял, что это проблема с цветовым пространством. Просто замените 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);
3 голосов
/ 11 июня 2013

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

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

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

Ура!

3 голосов
/ 24 октября 2011

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

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

+(CGSize)  fixSize:(CGSize) forSize{
    NSInteger w = (NSInteger) forSize.width;
    NSInteger h = (NSInteger) forSize.height;
    return CGSizeMake(w, h);
}
0 голосов
/ 17 августа 2013

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

...