4

I have a raspberry pi 3 which is running android things on it. I have attached the camera, and I can also see the output in Peripherals -> Camera. I also want to get a preview of the camera and do image processing on each frame. Using CameraX api, I have used the code found here.

Here is the code:

MainActivity.kt:

package com.example.sos_project

import android.graphics.Matrix
import android.os.Bundle
import android.util.Size
import android.view.Surface
import android.view.TextureView
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraX
import androidx.camera.core.Preview
import androidx.camera.core.PreviewConfig

/**
 * Skeleton of an Android Things activity.
 *
 * Android Things peripheral APIs are accessible through the class
 * PeripheralManagerService. For example, the snippet below will open a GPIO pin and
 * set it to HIGH:
 *
 * <pre>{@code
 * val service = PeripheralManagerService()
 * val mLedGpio = service.openGpio("BCM6")
 * mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
 * mLedGpio.value = true
 * }</pre>
 * <p>
 * For more complex peripherals, look for an existing user-space driver, or implement one if none
 * is available.
 *
 * @see <a href="https://github.com/androidthings/contrib-drivers#readme">https://github.com/androidthings/contrib-drivers#readme</a>
 *
 */
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewFinder = findViewById(R.id.view_finder)
        viewFinder.post { startCamera() }

        viewFinder.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
            updateTransform()
        }
    }

    private lateinit var viewFinder: TextureView

    private fun startCamera() {

        // Create configuration object for the viewfinder use case
        val previewConfig = PreviewConfig.Builder().apply {
            setTargetResolution(Size(640,480))
            setLensFacing(CameraX.LensFacing.FRONT)
        }.build()


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

        // Every time the viewfinder is updated, recompute layout
        preview.setOnPreviewOutputUpdateListener {

            // To update the SurfaceTexture, we have to remove it and re-add it
            val parent = viewFinder.parent as ViewGroup
            parent.removeView(viewFinder)
            parent.addView(viewFinder, 0)

            viewFinder.surfaceTexture = it.surfaceTexture
            updateTransform()
        }

        // Bind use cases to lifecycle
        // If Android Studio complains about "this" being not a LifecycleOwner
        // try rebuilding the project or updating the appcompat dependency to
        // version 1.1.0 or higher.
        CameraX.bindToLifecycle(this, preview)
    }

    private fun updateTransform() {
        val matrix = Matrix()

        // Compute the center of the view finder
        val centerX = viewFinder.width / 2f
        val centerY = viewFinder.height / 2f

        // Correct preview output to account for display rotation
        val rotationDegrees = when(viewFinder.display.rotation) {
            Surface.ROTATION_0 -> 0
            Surface.ROTATION_90 -> 90
            Surface.ROTATION_180 -> 180
            Surface.ROTATION_270 -> 270
            else -> return
        }
        matrix.postRotate(-rotationDegrees.toFloat(), centerX, centerY)

        // Finally, apply transformations to our TextureView
        viewFinder.setTransform(matrix)
    }
}

Complete error:

2019-11-21 11:03:33.555 3823-3823/com.example.___ E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.___, PID: 3823
    java.lang.IllegalArgumentException: Fail to find supported surface info - CameraId:null
        at androidx.camera.camera2.impl.Camera2DeviceSurfaceManager.requiresCorrectedAspectRatio(Camera2DeviceSurfaceManager.java:274)
        at androidx.camera.core.Preview.updateUseCaseConfig(Preview.java:476)
        at androidx.camera.core.UseCase.<init>(UseCase.java:96)
        at androidx.camera.core.Preview.<init>(Preview.java:115)
        at com.example.___.MainActivity.startCamera(MainActivity.kt:60)
        at com.example.___.MainActivity.access$startCamera(MainActivity.kt:35)
        at com.example.___.MainActivity$onCreate$1.run(MainActivity.kt:41)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

EDIT: I have tried to implement the same thing with java and I am getting the same error

java.lang.IllegalArgumentException: Unable to get camera ID for use case androidx.camera.core.Preview

What is wrong in my code?

Thanks in advance

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Arush Gupta
  • 81
  • 1
  • 7
  • 1
    I have solved the problem by not using cameraX for now and used Camera2Api. But there must be some solution to this CameraX problem as Camera2 is very difficult to understand and implement – Arush Gupta Dec 02 '19 at 16:53
  • https://issuetracker.google.com/issues/147986229 – JSONParser Jan 22 '20 at 02:40
  • according to the issue the problem got resolved. But i just got the exact same issue when using CameraX on emulator at github actions. – Hatzen Feb 20 '21 at 18:58

0 Answers0