Получение UIImage из CIImage не работает должным образом

У меня проблемы с получением UIImage из и CIImage. Строка кода ниже отлично работает на iOS6: (Выходное изображение — CIImage)

self.imageView = [UIImage imageWithCIImage:outputImage];

or

[self.imageView setImage:[UIImage imageWithCIImage:outputImage]];

Когда я запускаю эту же строку кода на устройстве под управлением iOS 5, imageView пуст. Если я регистрирую свойство размера UIImage, оно правильное, но изображение никогда не отображается на экране.

Когда я использую CGImageRef (как показано ниже), он отлично работает на обоих устройствах, но вызывает огромный рост памяти, когда я выполняю анализ кучи.

context = [CIContext contextWithOptions:nil];
CGImageRef ref = [context createCGImage:outputImage fromRect:outputImage.extent];
self.imageView.image = [UIImage imageWithCGImage:ref scale:1.0 orientation:UIImageOrientationUp];
CGImageRelease(ref);

Кто-нибудь знает, почему UIImage imageWithCIImage не работает? Согласно ссылке на класс UIImage, он должен работать на iOS5 и выше. Также почему использование CGImageRef вызывает такой значительный рост кучи?

Спасибо


person dana0550    schedule 15.10.2012    source источник


Ответы (1)


В iOS 5.0 -imageWithCIImage: никогда не работал должным образом, и нам сказали использовать подход -createCGImage:fromRect:, который вы описали выше, чтобы преобразовать цепочку фильтров Core Image в растровый вывод.

Как вы видите, недостатком этого является то, что -createCGImage:fromRect: создает новый CGImageRef с размером вашего целевого изображения, а растровое изображение в его основе передается вашему новому UIImage. Это, вероятно, означает, что у вас есть как минимум два полных растровых изображения, представляющих ваш последний отфильтрованный кадр в памяти в одной точке, что может вызвать значительный всплеск, если это большие изображения.

Похоже, что -imageWithCIImage: было исправлено в iOS 6.0 (в Core Image было сделано много улучшений с 5.0 до 6.0). Хотя я могу только догадываться, почему это не приводит к скачку памяти, держу пари, это связано с использованием кэша текстур для разделения памяти между выходной текстурой OpenGL ES из процесса фильтрации и окончательным растровым изображением, которое хранится в вашем UIImage. Я делаю это в своей структуре GPUImage, чтобы сократить потребление памяти при фильтрации больших изображений, и было бы разумно, чтобы Core Image делал то же самое. Опять же, это всего лишь предположение.

К сожалению, похоже, вам придется провести здесь небольшое тестирование версии и вернуться к старому способу получения вывода из CIImages, если вы хотите поддерживать iOS 5.0 в своем приложении.

person Brad Larson    schedule 15.10.2012
comment
Бред спасибо за ответ. Вчера по пути домой я прокручивал в голове эту проблему и, кажется, нашел решение. Я очень ценю ваш ответ, и я заметил, что этот вопрос задавался раньше. Основная проблема с использованием CGImageRef заключается в том, что куча постоянно растет, даже если я освобождаю объект. Я опубликую свое решение ниже после небольшого тестирования на инструментах, но мне нравится ваш подход к тестированию версий. Еще раз спасибо. - person dana0550; 16.10.2012
comment
Я обнаружил, что imageWithCIImage по-прежнему сильно глючит с iOS 8. - person jjxtra; 12.03.2015
comment
@ dana0550 Вы когда-нибудь находили оптимальное решение этой проблемы? Похоже, что imageWithCIImage по-прежнему глючит в iOS 8. - person Montas; 26.08.2015
comment
Кажется, в iOS 12 тоже есть ошибки. - person Wizard; 17.10.2018