Набор изображений графического процессора Android и getBitmapWithFilterApplied вызывают мерцание экрана

#android #kotlin #gpuimage #android-camerax

#Android #kotlin #изображение графического процессора #android-camerax

Вопрос:

Я использовал этот github в качестве начала своего кода: https://github.com/xizhang/camerax-gpuimage

Код — это способ показать вид камеры с фильтрами GPUImage на нем. Я хочу иметь возможность также анализировать растровое изображение с примененным к нему фильтром, чтобы получить некоторую аналитику (процент красного / зеленого / синего на изображении).

Мне удалось показать пользователю вид камеры по умолчанию, а также созданный мной фильтр.

Закомментировав строку кода setImage, я смог получить аналитику отфильтрованного изображения, но когда я пытаюсь сделать оба одновременно, экран мерцает. Я изменил функцию StartCameraIfReady, чтобы получить отфильтрованное изображение следующим образом:

     @SuppressLint("UnsafeExperimentalUsageError")
    private fun startCameraIfReady() {
        if (!isPermissionsGranted() || cameraProvider == null) {
            return;
        }
        val imageAnalysis = ImageAnalysis.Builder().setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build()
        imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer {
            var bitmap = allocateBitmapIfNecessary(it.width, it.height)
            converter.yuvToRgb(it.image!!, bitmap)
            it.close()
            gpuImageView.post {
                // These two lines conflict causing the screen to flicker
                // I can comment out one or the other and it works great
                // But running both at the same time causes issues
                gpuImageView.gpuImage.setImage(bitmap)
                val filtered = gpuImageView.gpuImage.getBitmapWithFilterApplied(bitmap)

                /*
                Analyze the filtered image...
                Print details about image here
                 */
            }
        })
        cameraProvider!!.unbindAll()
        cameraProvider!!.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, imageAnalysis)
    }
  

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

https://imgur.com/a/mXeuEhe

 <blockquote class="imgur-embed-pub" lang="en" data-id="a/mXeuEhe"  ><a href="//imgur.com/a/mXeuEhe">screenRocord</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>  

Ответ №1:

Если вы собираетесь получить растровое изображение с примененным фильтром, вам даже не нужен GPUImageView. Вы можете просто получить растровое изображение, а затем установить его на обычное изображение. Вот как должен выглядеть ваш анализатор:

 ImageAnalysis.Analyzer {
   var bitmap = allocateBitmapIfNecessary(it.width, it.height)
   converter.yuvToRgb(it.image!!, bitmap)
   it.close()
   val filteredBitmap = gpuImage.getBitmapWithFilterApplied(bitmap)
   regularImageView.post {
      regularImageView.setImageBitmap(filteredBitmap)
   }
}
  

Пожалуйста, имейте в виду, что исходный образец GitHub неэффективен, а приведенный выше пример еще хуже, потому что они преобразуют выходные данные в растровое изображение перед отправкой его обратно в GPU. Для лучшей производительности аргументации потока предварительного просмотра, пожалуйста, ознакомьтесь с основным тестовым приложением CameraX о том, как получить доступ к поверхности предварительного просмотра через OpenGL.