Как преобразовать текстуру OpenGL ES в CIImage

Я знаю, как сделать это наоборот. Но как я могу создать CIImage из текстуры, не копируя ее в память процессора? [Изображение CIImage с данными]? CVOpenGLESTTextureCache?


person akaru    schedule 26.01.2012    source источник
comment
Просто обновление для iOS 6, теперь это возможно.   -  person akaru    schedule 22.12.2012


Ответы (3)


К сожалению, я не думаю, что есть способ избежать необходимости считывать данные пикселей с помощью glReadPixels(). Все входные данные для CIImage (данные, CGImageRef, CVPixelBufferRef) находятся на стороне процессора, поэтому я не вижу быстрого пути для доставки их в CIImage. Похоже, что вашей лучшей альтернативой будет использование glReadPixels() для извлечения необработанных данных RGBA из вашей текстуры и отправки их в CIImage с использованием -initWithData:options: и формата kCIFormatRGBA8 пикселей. (Обновление: 14.03.2012) В iOS 5.0 теперь есть более быстрый способ получения данных кадра OpenGL ES с использованием новых кэшей текстур. Я подробно описываю это в этом ответе.

Однако может быть и другой способ добиться желаемого. Если вы просто хотите применить фильтры к текстуре для вывода на экран, вы можете использовать мою структуру GPUImage для обработки. Он уже использует OpenGL ES 2.0 в качестве ядра своего конвейера рендеринга, а текстуры — это способ передачи кадров изображений или видео от одного фильтра к другому. В моих тестах он также намного быстрее, чем Core Image.

Вы можете предоставить свою текстуру в качестве входных данных здесь, чтобы она никогда не касалась процессора. У меня пока нет стандартного класса для захвата необработанных текстур из OpenGL ES, но вы можете изменить код одного из существующих подклассов GPUImageOutput, чтобы довольно легко использовать его в качестве источника. Затем вы можете связать фильтры с этим и направить вывод на экран или на неподвижное изображение. В какой-то момент я добавлю класс для такого источника данных, но проект все еще довольно новый.

person Brad Larson    schedule 17.02.2012
comment
Спасибо, Брэд. Вы работали с CVOpenGLESTextureCache? Кажется, это должно быть альтернативой glReadPixels, если нет другого пути. Есть метод только для моего вопроса об OS X, и кажется, что должен быть способ из-за того, как Apple фокусируется на графических процессорах... - person akaru; 18.02.2012
comment
@akaru - Если я что-то не упустил, CVOpenGLESTextureCache предназначен только для быстрой однонаправленной загрузки текстур. Я не думаю, что его можно использовать для чтения чего-либо из текстуры OpenGL ES. Ни в шапках, ни в презентациях Apple по теме я не встречал упоминаний об этом. Я думаю, что мы застряли с glReadPixels() на iOS. - person Brad Larson; 18.02.2012
comment
@akaru - я не могу найти ваш предыдущий вопрос об этом, но оказалось, что я ошибался в том, что кэши текстур были однонаправленными. Я только что заставил их кодировать видео, и они намного быстрее, чем glReadPixels(): stackoverflow.com/a/9704392/19679 - person Brad Larson; 14.03.2012

Начиная с iOS 6, вы можете использовать встроенный метод инициализации для этой ситуации:

initWithTexture:size:flipped:colorSpace:

См. документы: http://developer.apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/QuartzCoreFramework/Classes/CIImage_Class/Reference/Reference.html

person Matt Logan    schedule 19.07.2013

Вы можете найти это полезным:

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

person SundayMonday    schedule 17.02.2012