iPhone:Изменение CGImageAlphaInfo для CGImage
-
20-09-2019 - |
Вопрос
У меня есть изображение в формате PNG, которое имеет неподдерживаемый растровый графический контекстный пиксельный формат.Всякий раз, когда я пытаюсь изменить размер изображения, CGBitmapContextCreate()
блокируется неподдерживаемый формат
Я получаю следующую ошибку (ошибка отформатирована для удобства чтения):
CGBitmapContextCreate: unsupported parameter combination:
8 integer bits/component;
32 bits/pixel;
3-component colorspace;
kCGImageAlphaLast;
1344 bytes/row.
Тот Самый список поддерживаемых форматов пикселей определенно не поддерживает эту комбинацию.Похоже, мне нужно перерисовать изображение и переместить информацию об альфа-канале в kCGImageAlphaPremultipliedFirst или kCGImageAlphaPremultipliedLast.
Я понятия не имею, как это сделать.
В файле PNG нет ничего необычного, и он не поврежден.Это прекрасно работает во всех других контекстах.Я столкнулся с этой ошибкой совершенно случайно, но, очевидно, у моих пользователей могли быть файлы аналогичного формата, поэтому мне придется проверить импортированные изображения моего приложения и исправить эту проблему.
Решение
Да, у меня были проблемы с 8-битными (индексированными) .PNGS.Мне пришлось преобразовать его в более нативное изображение для выполнения графических операций.По сути, я сделал что-то вроде этого:
- (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;
}
Другие советы
Вот обновленная версия метода из ответа Альфонса для учета масштаба экрана, а также некоторые глупые ошибки с десятичными знаками в значениях размера изображения с плавающей запятой, как описано в комментарии unsynchronized из исходного ответа.
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;
}