Android SDK: получить предварительный просмотр изображения камеры без его отображения
Я хочу выполнить обработку изображения с необработанным изображением, не показывая его на экране, что, очевидно, снижает производительность.
В соответствии с ответами на эту тему: Снимать фотографию с камеры без предварительного просмотра было невозможно в Android 1.5, но кто-нибудь знает, возможно ли это в Android 4 (уровень API 15)?
3 ответа
В Android 4 самым простым вариантом получения необработанных данных изображения без их отображения на экране является использование вызова Camera.setPreviewTexture() для маршрутизации кадров предварительного просмотра в графический процессор.
Вы можете использовать это двумя способами:
- Выполните фактическую обработку на графическом процессоре: настройте контекст OpenGL ( учебное пособие по OpenGL ES 2) и создайте объект SurfaceTexture в этом контексте. Затем передайте этот объект в setPreviewTexture и запустите предварительный просмотр. Затем в своем коде OpenGL вы можете вызвать SurfaceTexture.updateTexImage, и идентификатор текстуры, связанный с SurfaceTexture, будет обновлен до самого последнего кадра предварительного просмотра с камеры. Вы также можете прочитать данные текстуры RGB в ЦП для дальнейшей обработки, используя glReadPixels, если это необходимо.
- Выполните обработку в ЦП: вы можете просто создать фиктивный объект SurfaceTexture без какой-либо настройки контекста OpenGL. Передайте любое целое число в качестве идентификатора текстуры и подключите SurfaceTexture к камере, используя setPreviewTexture. Пока вы не вызываете updateTexImage, SurfaceTexture будет просто отбрасывать все данные, переданные в нее камерой. Затем настройте обратные вызовы предварительного просмотра с помощью setPreviewCallback и используйте эти данные (обычно в формате YUV) для обработки ЦП. Это, вероятно, менее эффективно, чем #1, но не требует знания OpenGL.
Отображение предварительного просмотра на экране не имеет последствий для производительности. На всех устройствах, с которыми я встречался, выход камеры "подключен" к поверхности или текстуре без использования процессора, все преобразования цвета и масштабирование выполняются специальным оборудованием.
Могут быть и другие причины, чтобы "скрыть" предварительный просмотр, но имейте в виду, что изначально целью API было убедиться, что конечный пользователь видит все, что поступает с камеры в приложение, из соображений конфиденциальности и безопасности.
Поскольку я не могу комментировать. Относительно ответа Эдди. Вы должны работать с этим в NDK, так как использование интерфейса Java сведет на нет любое повышение производительности. Работать с PixelBuffer абсолютно безумно с точки зрения производительности. Ваше преобразование из RGBA888 в YUV также должно быть сделано в C.
Не пытайтесь использовать TextureView, так как это будет еще хуже. Вам нужно будет скопировать пиксели в растровое изображение, а затем из растрового изображения в массив, перед преобразованием в YUV. Это само по себе занимает почти 30% от загрузки процессора на новом Nexus 7 2013.
Наиболее эффективный способ - напрямую общаться с Camera.h и обходить все API-интерфейсы Android. Вы можете создать свой собственный буфер и перехватывать данные YUV, прежде чем они отправятся куда-либо еще.