Android: как отобразить предварительный просмотр камеры с обратным вызовом?

То, что мне нужно сделать, довольно просто: я хочу вручную отображать предварительный просмотр с камеры с помощью обратного вызова камеры, и я хочу получить как минимум 15 кадров в секунду на реальном устройство. Мне даже не нужны цвета, мне просто нужно предварительно просмотреть изображение в оттенках серого. Изображения с камеры находятся в формате YUV, и вам нужно как-то их обработать, что является основной проблемой производительности. Я использую API 8.

Во всех случаях я использую camera.setPreviewCallbackWithBuffer (), что быстрее, чем camera.setPreviewCallback (). Кажется, я не могу получить здесь около 24 кадров в секунду, если я не показываю превью. Так что проблема не в этом.

Я пробовал следующие решения:

1. Предварительный просмотр камеры на SurfaceView в виде растрового изображения. Работает, но скорость около 6 кадров в секунду.

baos = new ByteOutputStream();
yuvimage=new YuvImage(cameraFrame, ImageFormat.NV21, prevX, prevY, null);

yuvimage.compressToJpeg(new Rect(0, 0, prevX, prevY), 80, baos);
jdata = baos.toByteArray();

bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length); // Convert to Bitmap, this is the main issue, it takes a lot of time

canvas.drawBitmap(bmp , 0, 0, paint);


2. Предварительный просмотр камеры на GLSurfaceView в виде текстуры. Здесь я отображал только данные о яркости (изображение в оттенках серого), что довольно просто, для этого требуется только одна arraycopy () для каждого кадра. Я могу получить около 12 кадров в секунду, но мне нужно применить некоторые фильтры к предварительному просмотру, и кажется, что это не может быть сделано быстро в OpenGL ES 1. Поэтому я не могу использовать это решение. Некоторые подробности этого в , другом вопросе .


3. Отобразите предварительный просмотр камеры на (GL) SurfaceView, используя NDK для обработки данных YUV. Я нахожу решение здесь , которое использует некоторую функцию C и NDK. Но мне не удалось его использовать, вот подробности . Но в любом случае это решение сделано для возврата ByteBuffer для отображения его в виде текстуры в OpenGL, и это не будет быстрее, чем предыдущая попытка. Поэтому мне пришлось бы изменить его, чтобы он возвращал массив int [], который можно нарисовать с помощью canvas.drawBitmap (), но я недостаточно понимаю C, чтобы сделать это.


Итак, есть ли какие-нибудь Другой способ, которым я пропустил, или какое-то улучшение по сравнению с попытками, которые я пробовал?

14
задан Jaa-c 29 August 2018 в 08:01
поделиться