【问题标题】:How can I display a negative mode preview with CameraX in Android?如何在 Android 中使用 CameraX 显示否定模式预览?
【发布时间】:2019-12-30 04:36:03
【问题描述】:

我正在学习 CameraX API,CameraXBasic 是一个 office 示例代码。

CameraXBasic 项目中的

CameraFragment.kt 显示真实的相机预览。

现在我希望显示一个否定模式预览。如何使用 CameraX API?有示例代码吗?

CameraFragment.kt

private lateinit var viewFinder: TextureView

private fun bindCameraUseCases() {
    // Get screen metrics used to setup camera for full screen resolution
    val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
    val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)
    Log.d(TAG, "Screen metrics: ${metrics.widthPixels} x ${metrics.heightPixels}")

    // Set up the view finder use case to display camera preview
    val viewFinderConfig = PreviewConfig.Builder().apply {
        setLensFacing(lensFacing)
        // We request aspect ratio but no resolution to let CameraX optimize our use cases
        setTargetAspectRatio(screenAspectRatio)
        // Set initial target rotation, we will have to call this again if rotation changes
        // during the lifecycle of this use case
        setTargetRotation(viewFinder.display.rotation)
    }.build()

    // Use the auto-fit preview builder to automatically handle size and orientation changes
    preview = AutoFitPreviewBuilder.build(viewFinderConfig, viewFinder)

 ....

 CameraX.bindToLifecycle(
            viewLifecycleOwner, preview, imageCapture, imageAnalyzer)
}

【问题讨论】:

标签: android android-camerax


【解决方案1】:

这是一个应用于SurfaceTextureandroid.media.effect.EffectPreviewConfig 没有任何此类属性)。见EffectFactory.EFFECT_NEGATIVE:

/**
 * Applies negative film effect on image.<br/>
 * Parameters: scale (float): the degree of film grain.
**/
public final static String EFFECT_NEGATIVE = "android.media.effect.effects.NegativeEffect";

Here 也有解释(Kotlin 和 Java 文档的组织方式不同)。

但是,您可能需要使用自己的SurfaceTexture,否则很难获得 GLContext。这个例子几乎可以工作,但是texture.attachToGLContext():

private EffectContext fxContext = null;
private EffectFactory fxFactory = null;
private Effect fx = null;

protected void applyNegativeEffect(SurfaceTexture texture, int width, int height) {
    if(this.fxContext == null) {
        // texture.attachToGLContext(texture.mSurfaceTexture);
        this.fxContext = EffectContext.createWithCurrentGlContext();
    }
    if(this.fxFactory == null) {
        this.fxFactory = this.fxContext.getFactory();
    }
    if(this.fx == null) {
        this.fx = fxFactory.createEffect(EffectFactory.EFFECT_NEGATIVE);
        this.fx.setParameter("scale", 1.0f);
        // this.fx.apply(0, width, height, 0);
    }
}

SurfaceTexturelong mSurfaceTexture 需要暴露)显示:

/**
 * These fields are used by native code, do not access or modify.
**/
private long mSurfaceTexture;

GLSurfaceView 上设置着色器可能更容易完成:

String shader = "#extension GL_OES_EGL_image_external : require\n"
    + "precision mediump float;\n"
    + "varying vec2 vTextureCoord;\n"
    + "uniform samplerExternalOES sTexture;\n"
    + "void main() {\n"
    + "  vec4 color = texture2D(sTexture, vTextureCoord);\n"
    + "  float colorR = (1.0 - color.r) / 1.0;\n"
    + "  float colorG = (1.0 - color.g) / 1.0;\n"
    + "  float colorB = (1.0 - color.b) / 1.0;\n"
    + "  gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n"
    + "}\n";

还有一个摄像头2 example 用于 OpenGL ES 预览。

从 CameraX 抽象中获取 GLContext 是真正的问题,因为需要使用自定义 OpenGL 预览构建 androidx.camera.core,以便应用着色器 - 或获取输入/输出 texId

更新

Implement a preview 读取:

如果您需要直接访问SurfaceTexture,例如执行OpenGL 渲染,请参阅Manually create a SurfaceTexture。在这些情况下,使用Preview.PreviewSurfaceProviderSurfaceTexture 传递给Preview 对象。

查看问题问题#146957342Futures.immediateFuture(surface) 不再起作用。

【讨论】:

  • 谢谢!你的意思是在 Android 中使用 CameraX 显示否定模式预览有点困难,因为我们无法从 CameraX 获取 GLContext 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多