Как связать предварительный просмотр и текстуру в CameraX - PullRequest
0 голосов
/ 16 мая 2019

Недавно я попытался разработать плагин флаттера с cameraX, но обнаружил, что просто невозможно связать Preview с текстурой флаттера.

В прошлом мне нужно было использовать только camera.setPreviewTexture (surfaceTexture.surfaceTexture ()) для привязки камеры и текстуры, теперь я не могу найти API.

camera.setPreviewTexture(surfaceTexture.surfaceTexture())
        val previewConfig = PreviewConfig.Builder().apply {
            setTargetAspectRatio(Rational(1, 1))
            setTargetResolution(Size(640, 640))
        }.build()

        // Build the viewfinder use case
        val preview = Preview(previewConfig).also{

        }

        preview.setOnPreviewOutputUpdateListener {
//            it.surfaceTexture = this.surfaceTexture.surfaceTexture()
        }

   // how to bind the CameraX Preview surfaceTexture and flutter surfaceTexture?

1 Ответ

1 голос
/ 16 мая 2019

Кажется, что использование CameraX трудно или невозможно из-за того, что оно абстрагирует более сложные вещи, и поэтому не раскрывает такие вещи, которые вам нужны, например, возможность передавать в свою собственную SurfaceTexture (которая обычно создается Flutter).

Итак, простой ответ - вы не можете использовать CameraX.

Как говорится, с некоторой работой вы можете иметь возможность заставить это работать, но я понятия не имею, сработает ли это наверняка. Это уродливо и непристойно, поэтому я бы не советовал. YMMV.


Если мы собираемся сделать это, давайте сначала посмотрим, как представление флаттера создает текстуру

    @Override
    public TextureRegistry.SurfaceTextureEntry createSurfaceTexture() {
        final SurfaceTexture surfaceTexture = new SurfaceTexture(0);
        surfaceTexture.detachFromGLContext();
        final SurfaceTextureRegistryEntry entry = new SurfaceTextureRegistryEntry(nextTextureId.getAndIncrement(),
                surfaceTexture);
        mNativeView.getFlutterJNI().registerTexture(entry.id(), surfaceTexture);
        return entry;
    }

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

Вы можете получить текстуру, которую камера создает следующим образом:

preview.setOnPreviewOutputUpdateListener { previewOutput ->
    SurfaceTexture texture = previewOutput.surfaceTexture
}

Что вам нужно сделать сейчас, это передать ссылку на ваш FlutterView в ваш плагин (я оставлю это для вас, чтобы разобраться). Затем позвоните flutterView.getFlutterNativeView(), чтобы получить доступ к FlutterNativeView.

К сожалению, getFlutterJni от FlutterNativeView является частным пакетом. Так что это то, где это становится действительно хакерским - вы можете создать класс в том же пакете, который вызывает этот закрытый для пакета метод в общедоступном методе. Это ужасно, и вам, возможно, придется возиться с Gradle, чтобы настройки безопасности компиляции позволили это сделать, но это должно быть возможно.

После этого должно быть достаточно просто создать SurfaceTextureRegistryEntry и зарегистрировать текстуру с помощью флаттера jni. Я не думаю, что вы хотите отсоединиться от контекста opengl, и я действительно не знаю, сработает ли это на самом деле. Но если вы хотите попробовать и сообщить, что вы нашли, мне было бы интересно услышать результат!

...