从camera2 API,Android Studio,Kotlin捕获并显示图像

时间:2019-01-21 15:25:51

标签: kotlin android-camera2

我一直在遵循有关如何在片段上获取相机预览以在我的应用程序上显示的教程,我是kotlin的新手,但已经在Swift中编程了2年。有没有一种方法可以从预览中获取图像并将其显示在另一个图像视图中。

我创建了一个名为imageGotCont的图像视图,这是我要在图像的主要活动中放置图像的位置,因此当我按下按钮时,我需要一个从预览中获取图像并将其放置在图像中的功能。视图。

下面是片段。

class FragmentCameraPreview : Fragment() {


    private val MAX_DISPLAY_WIDTH = 1280
    private val MAX_DISPLAY_HEIGHT = 720
    private lateinit var captureSession: CameraCaptureSession
    private lateinit var captureRequestBuilder: CaptureRequest.Builder
    private lateinit var imageSize: Size
    private lateinit var cameraDevice: CameraDevice


    private val deviceStateCallback = object : CameraDevice.StateCallback() {

        override fun onOpened(camera: CameraDevice?) {
            Log.d(TAG, "camera device opened")
            if (camera != null) {
                cameraDevice = camera
                previewSession()
            }
        }

        override fun onDisconnected(camera: CameraDevice?) {
            Log.d(TAG, "camera device disconnected")
            camera?.close()
        }

        override fun onError(camera: CameraDevice?, error: Int) {
            Log.d(TAG, "camera device error")
            this@FragmentCameraPreview.activity?.finish()
        }

    }
    private lateinit var backgroundThread: HandlerThread
    private lateinit var backgroundHandler: Handler

    private val cameraManager by lazy {
        activity?.getSystemService(Context.CAMERA_SERVICE) as CameraManager

    }


    companion object {
        private val TAG = FragmentCameraPreview::class.qualifiedName
        const val REQUEST_CAMERA_PERMISSION = 100
        @JvmStatic
        fun newInstance() = FragmentCameraPreview()
    }

    private val surfaceListner = object : TextureView.SurfaceTextureListener {
        override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {
        }

        override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) = Unit

        override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean = true

        override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
            Log.d(TAG, "Tony texture surface width: $width height: $height")
            openCamera()
        }

    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    @AfterPermissionGranted(REQUEST_CAMERA_PERMISSION)
    private fun checkCameraPermission() {
        if (EasyPermissions.hasPermissions(activity!!, android.Manifest.permission.CAMERA)) {
            Log.d(TAG, "APP has camera permission")
            connectCamera()
        } else {
            EasyPermissions.requestPermissions(
                activity!!,
                getString(R.string.camera_request_rationale),
                REQUEST_CAMERA_PERMISSION,
                android.Manifest.permission.CAMERA
            )
        }
    }

    override fun onResume() {
        super.onResume()

        startBackgroundThread()
        if (previewTextureView.isAvailable)
            openCamera()
        else
            previewTextureView.surfaceTextureListener = surfaceListner
    }

    override fun onPause() {
        closeCamera()
        stopBackgroundThread()
        super.onPause()
    }


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        val myInflatedView = inflater.inflate(R.layout.fragment_camera_preview, container, false)


        return myInflatedView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        activity?.window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN or
                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN or
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    }

    private fun openCamera() {
        checkCameraPermission()
    }

    private fun <T> cameraCharacteristics(cameraId: String, key: CameraCharacteristics.Key<T>): T {
        val characteristics = cameraManager.getCameraCharacteristics(cameraId)
        return when (key) {
            CameraCharacteristics.LENS_FACING -> characteristics.get(key)
            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP -> characteristics.get(key)
            else -> throw IllegalArgumentException("Key not recognized")
        }
    }

    private fun cameraId(lens: Int): String {
        var deviceId = listOf<String>()

        try {
            val cameraIdList = cameraManager.cameraIdList

            deviceId = cameraIdList.filter { lens == cameraCharacteristics(it, CameraCharacteristics.LENS_FACING) }
        } catch (e: CameraAccessException) {
            Log.e(TAG, e.toString())
        }
        return deviceId[0]
    }

    private fun connectCamera() {
        val deviceID = cameraId(CameraCharacteristics.LENS_FACING_BACK)
        Log.d(TAG, "deviceID: $deviceID")
        try {
            cameraManager.openCamera(deviceID, deviceStateCallback, backgroundHandler)
        } catch (e: CameraAccessException) {
            Log.e(TAG, e.toString())
        } catch (e: InterruptedException) {
            Log.e(TAG, "Open camera device interrupted while opening")
        }
    }

    private fun startBackgroundThread() {
        backgroundThread = HandlerThread("CameraKotlin").also { it.start() }
        backgroundHandler = Handler(backgroundThread.looper)
    }

    private fun stopBackgroundThread() {
        backgroundThread.quitSafely()
        try {
            backgroundThread.join()
        } catch (e: InterruptedException) {
            Log.e(TAG, e.toString())
        }
    }

    private fun previewSession() {
        val surfaceTexture = previewTextureView.surfaceTexture
        surfaceTexture.setDefaultBufferSize(MAX_DISPLAY_WIDTH, MAX_DISPLAY_HEIGHT)
        val surface = Surface(surfaceTexture)

        captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
        captureRequestBuilder.addTarget(surface)

        cameraDevice.createCaptureSession(
            Arrays.asList(surface),
            object : CameraCaptureSession.StateCallback() {
                override fun onConfigureFailed(session: CameraCaptureSession?) {
                    Log.e(TAG, "creating capture session failed")
                }

                override fun onConfigured(session: CameraCaptureSession?) {
                    if (session != null) {
                        captureSession = session
                        captureRequestBuilder.set(
                            CaptureRequest.CONTROL_AF_MODE,
                            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE
                        )
                        captureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null)
                    }
                }

            }, null
        )
    }

    private fun closeCamera() {
        if (this::captureSession.isInitialized)
            captureSession.close()
        if (this::cameraDevice.isInitialized)
            cameraDevice.close()
    }
}

0 个答案:

没有答案