Android SDK: получить изображение предварительного просмотра камеры без его отображения

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

В соответствии с ответами на эту тему Съемка с камеры без предварительного просмотра в Android 1.5 это было невозможно, но кто-нибудь знает, возможно ли это в Android 4 ( API-уровень 15)?

Ответ 1

В Android 4 самым простым вариантом получения необработанных данных изображения без отображения на экране является использование вызова Camera.setPreviewTexture() для маршрутизации кадров предварительного просмотра GPU.

Вы можете использовать это двумя способами:

  • Сделайте свою фактическую обработку на графическом процессоре: настройте контекст OpenGL (учебник OpenGL ES 2) и создайте SurfaceTexture в этом контексте. Затем передайте этот объект в setPreviewTexture и начните предварительный просмотр. Затем в вашем коде OpenGL вы можете вызвать SurfaceTexture.updateTexImage, а идентификатор текстуры, связанный с SurfaceTexture, будет обновлен до последнего кадра предварительного просмотра с камеры. Вы также можете прочитать данные текстуры RGB в CPU для дальнейшей обработки с помощью glReadPixels, если это необходимо.
  • Выполняйте свою обработку на процессоре: вы можете просто создать фиктивный объект SurfaceTexture без какого-либо контекста OpenGL. Передайте любое целое число, которое вы хотите в качестве идентификатора текстуры, и подключите SurfaceTexture к камере с помощью setPreviewTexture. Пока вы не вызываете updateTexImage, SurfaceTexture просто отбрасывает все данные, переданные в него камерой. Затем настройте предварительные обратные вызовы с помощью setPreviewCallback и используйте эти данные (как правило, в формате YUV) для обработки ЦП. Это, вероятно, менее эффективно, чем # 1, но не требует знания OpenGL.

Ответ 2

Так как мне не разрешено комментировать. Что касается ответа Эдди. Вам нужно работать с этим в NDK, поскольку использование интерфейса Java приведет к отрицательному результату. Необходимость работать с PixelBuffer абсолютно безумна с точки зрения производительности. Ваше преобразование из RGBA888 в YUV также должно быть выполнено на C.

Не пытайтесь использовать TextureView, так как это будет еще хуже. Вам нужно будет скопировать пиксели в битмап, а затем из растрового изображения в массив до преобразования в YUV. Это само по себе занимает почти 30% от использования процессора на бренде, который шлепает новый Nexus 7 2013.

Самый эффективный способ - напрямую поговорить с Camera.h и обойти все API Android. Вы можете создать свой собственный буфер и перехватить данные YUV, прежде чем он отправится куда угодно.

Ответ 3

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

Могут быть другие причины "скрыть" предварительный просмотр, но имейте в виду, что цель API первоначально заключалась в том, чтобы убедиться, что конечный пользователь видит все, что прибывает с камеры в приложение, в целях конфиденциальности и соображений безопасности.