iPhone: изменение CGImageAlphaInfo для CGImage - PullRequest
25 голосов
/ 16 марта 2010

У меня есть PNG-изображение, которое имеет неподдерживаемый растровый графический контекстный пиксельный формат. Всякий раз, когда я пытаюсь изменить размер изображения, CGBitmapContextCreate() задыхается от неподдерживаемого формата

Я получаю следующую ошибку (ошибка отформатирована для удобства чтения):

CGBitmapContextCreate: unsupported parameter combination: 
    8 integer bits/component; 
    32 bits/pixel; 
    3-component colorspace; 
    kCGImageAlphaLast; 
    1344 bytes/row.

Список поддерживаемых форматов пикселей определенно не поддерживает эту комбинацию. Кажется, мне нужно перерисовать изображение и переместить информацию альфа-канала в kCGImageAlphaPremultipliedFirst или kCGImageAlphaPremultipliedLast .

Я понятия не имею, как это сделать.

В файле PNG нет ничего необычного, и он не поврежден. Это работает во всех других контекстах просто отлично. Я случайно столкнулся с этой ошибкой, но, очевидно, мои пользователи могли иметь файлы аналогичного формата, поэтому мне придется проверить импортированные изображения моего приложения и исправить эту проблему.

Ответы [ 2 ]

56 голосов
/ 21 марта 2010

Да, у меня были проблемы с 8-битными (индексированными) .PNG. Мне пришлось преобразовать его в более родное изображение для выполнения графических операций. По сути, я сделал что-то вроде этого:

- (UIImage *) normalize {

    CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL, 
                                                         self.size.width, 
                                                         self.size.height, 
                                                         8, (4 * self.size.width), 
                                                         genericColorSpace, 
                                                         kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(genericColorSpace);
    CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);
    CGRect destRect = CGRectMake(0, 0, self.size.width, self.size.height);
    CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);
    CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);
    CGContextRelease(thumbBitmapCtxt);    
    UIImage *result = [UIImage imageWithCGImage:tmpThumbImage];
    CGImageRelease(tmpThumbImage);

    return result;    
}
5 голосов
/ 21 февраля 2012

Вот обновленная версия метода от ответа Alfons для учета масштаба экрана, а также некоторые глупые ошибки с десятичными числами в значениях размера с плавающей запятой, как описано в комментарии несинхронизированного из исходного ответа.

SCREEN_SCALE - это макрос, который возвращает либо 1,0, если масштаб не определен, либо независимо от того, масштаб устройства на самом деле ([UIScreen mainScreen] .scale).

- (UIImage *) normalize {

    CGSize size = CGSizeMake(round(self.size.width*SCREEN_SCALE), round(self.size.height*SCREEN_SCALE));
    CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL, 
                                                         size.width, 
                                                         size.height, 
                                                         8, (4 * size.width), 
                                                         genericColorSpace, 
                                                         kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(genericColorSpace);
    CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);
    CGRect destRect = CGRectMake(0, 0, size.width, size.height);
    CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);
    CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);
    CGContextRelease(thumbBitmapCtxt);    
    UIImage *result = [UIImage imageWithCGImage:tmpThumbImage scale:SCREEN_SCALE orientation:UIImageOrientationUp];
    CGImageRelease(tmpThumbImage);

    return result;    
}
...