我最近尝试用cameraX开发一个flutter插件,但是我发现无法简单地将Preview绑定到flutter的Texture。
过去,我只需要使用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?
答案 0 :(得分:3)
我认为您可以通过Preview.SurfaceProvider绑定纹理。
final CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
final ListenableFuture<ProcessCameraProvider> listenableFuture = ProcessCameraProvider.getInstance(appCompatActivity.getBaseContext());
listenableFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = listenableFuture.get();
Preview preview = new Preview.Builder()
.setTargetResolution(new Size(720, 1280))
.build();
cameraProvider.unbindAll();
Camera camera = cameraProvider.bindToLifecycle(appCompatActivity, cameraSelector, preview);
Preview.SurfaceProvider surfaceProvider = request -> {
Size resolution = request.getResolution();
surfaceTexture.setDefaultBufferSize(resolution.getWidth(), resolution.getHeight());
Surface surface = new Surface(surfaceTexture);
request.provideSurface(surface, ContextCompat.getMainExecutor(appCompatActivity.getBaseContext()), result -> {
});
};
preview.setSurfaceProvider(surfaceProvider);
} catch (Exception e) {
e.printStackTrace();
}
}, ContextCompat.getMainExecutor(appCompatActivity.getBaseContext()));
答案 1 :(得分:0)
由于使用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。
不幸的是,FlutterNativeView的getFlutterJni是包私有的。所以这才是真正的问题-您可以在同一包中创建一个类,该类以公开可访问的方法调用该package-private方法。这太丑陋了,您可能必须在Gradle上摆弄一下才能获得允许的编译安全设置,但这应该是可能的。
在那之后,创建一个SurfaceTextureRegistryEntry
并向flni jni注册纹理应该足够简单。我不认为您想脱离opengl上下文,而且我真的不知道这是否会真正起作用。但是,如果您想尝试一下并报告您发现的问题,我将有兴趣听到结果!