Как я могу отобразить предварительный просмотр негативного режима с помощью CameraX в Android?

Я изучаю CameraX API, а CameraXBasic - это образец кода для офиса.

CameraFragment.kt в проекте CameraXBasic отображает предварительный просмотр реальной камеры.

Теперь я надеюсь показать превью в негативном режиме. Как я могу использовать 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)
}

person HelloCW    schedule 25.11.2019    source источник
comment
Что такое negative mode?   -  person Froyo    schedule 03.12.2019
comment
Для этого вы можете использовать RenderScript. 1. Как использовать RenderScript с камеройX gist.github.com/LiewJunTung/b9b7fbe8444037f2. отрицательный эффект developer.android.com/reference/android/media/ эффект /   -  person Froyo    schedule 03.12.2019


Ответы (1)


Это android.media.effect.Effect, применяемое к SurfaceTexture ( PreviewConfig не имеет таких свойств). См. 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";

Здесь это также объясняется (документация по 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);
    }
}

Но SurfaceTexture (где long 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";

И пример для OpenGL камеры2 Предварительный просмотр ES.

Получение GLContext из абстракции CameraX является актуальной проблемой, потому что потребуется создать androidx.camera.core с настраиваемым предварительным просмотром OpenGL, чтобы применить шейдер или получить ввод / вывод texId.

Обновление:

Реализовать предварительный просмотр гласит:

Если вам требуется прямой доступ к SurfaceTexture, например для выполнения рендеринга OpenGL, см. Создание файла вручную SurfaceTexture. В этих случаях передайте SurfaceTexture объекту Preview, используя Preview.PreviewSurfaceProvider.

См. Проблему # 146957342, Futures.immediateFuture(surface) больше не работает.

person Martin Zeitler    schedule 03.12.2019
comment
Спасибо! Вы имеете в виду, что отображать предварительный просмотр в негативном режиме с помощью CameraX в Android немного сложно, потому что мы не можем получить GLContext из CameraX? - person HelloCW; 04.12.2019