模糊 CameraX 预览

问题描述 投票:0回答:1

我正在使用 CameraX 库构建布局的相机预览,我想模糊预览。我搜索了很多方法,但大多数都过时或太复杂。

现在我尝试参考CameraX:如何设置PreviewView的背景?中的模糊方法,但我的相机预览仍然不模糊。

我尝试将相机预览捕获为纹理视图并将其转换为位图,然后使用渲染脚本对其进行模糊处理。但是,我的日志一直显示“相机预览位图为空”。

MainActivity.kt

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_welcome)

        cameraPreview = findViewById(R.id.cameraPreview);
        cameraBtn = findViewById(R.id.cameraButton);
        blurOverlayImageView = findViewById(R.id.blurOverlay);

        // Request camera permission and initialize CameraX

            if (allPermissionsGranted()) {
                startCamera()
            } else {
                ActivityCompat.requestPermissions(
                    this, arrayOf(Manifest.permission.CAMERA), CAMERA_PERM_CODE
                )
            }


        cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture?.addListener({
            val cameraProvider = cameraProviderFuture?.get()
            bindPreview(cameraProvider)
        }, ContextCompat.getMainExecutor(this))

        cameraBtn.setOnClickListener {
            val intent = Intent(this, CameraActivity::class.java)
            startActivity(intent)

        }
    }

    private fun bindPreview(cameraProvider: ProcessCameraProvider?) {
        // Configure the preview use case
        val preview = Preview.Builder().build()
        val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()

        // Connect the preview to the PreviewView
        preview.setSurfaceProvider(cameraPreview.surfaceProvider)

        // Unbind any previous use cases before rebinding
        try {
            cameraProvider?.unbindAll()

            // Bind the camera use cases to the cameraProvider
            val camera = cameraProvider?.bindToLifecycle(this, cameraSelector, preview)
        } catch (exc: Exception) {
            // Handle exceptions here
        }
    }


    private fun allPermissionsGranted() = ActivityCompat.checkSelfPermission(
        this, Manifest.permission.CAMERA
    ) == PackageManager.PERMISSION_GRANTED

    private fun startCamera() {
        val cameraProvider = cameraProviderFuture?.get()
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        // Initialize the preview animator for continuous blur
        initializePreviewAnimator()

        val preview = Preview.Builder()
            .build()
            .also { it.setSurfaceProvider(cameraPreview.surfaceProvider) }

        try {
            cameraProvider?.unbindAll()
            val camera = cameraProvider?.bindToLifecycle(
                this, cameraSelector, preview
            )
        } catch (exc: Exception) {
            // Handle exceptions here
        }
    }


    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == CAMERA_PERM_CODE) {
            if (allPermissionsGranted()) {
                startCamera()
            } else {
                Toast.makeText(this, "Camera Permission is Required to Use the camera.", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun blurRenderScript(smallBitmap: Bitmap, radius: Int): Bitmap? {
        val defaultBitmapScale = 0.1f
        val width = (smallBitmap.width * defaultBitmapScale).roundToInt()
        val height = (smallBitmap.height * defaultBitmapScale).roundToInt()
        val inputBitmap = Bitmap.createScaledBitmap(smallBitmap, width, height, false)
        val outputBitmap = Bitmap.createBitmap(inputBitmap)
        val renderScript = RenderScript.create(this)
        val theIntrinsic = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
        val tmpIn = Allocation.createFromBitmap(renderScript, inputBitmap)
        val tmpOut = Allocation.createFromBitmap(renderScript, outputBitmap)
        theIntrinsic.setRadius(radius.toFloat())
        theIntrinsic.setInput(tmpIn)
        theIntrinsic.forEach(tmpOut)
        tmpOut.copyTo(outputBitmap)
        return outputBitmap
    }

    private fun initializePreviewAnimator() {
        // Initializing the preview animator with values to blur
        previewAnimator = ValueAnimator.ofInt(6, 12, 18, 24, 25)
        // Set the animation to repeat infinitely
        previewAnimator.repeatCount = ValueAnimator.INFINITE
        previewAnimator.repeatMode = ValueAnimator.RESTART

        // Setting animation duration for each frame (adjust as needed)
        //previewAnimator.duration = 100 // Set the duration for each frame (in milliseconds)

        // Adding listener for every value update of the animation
        previewAnimator.addUpdateListener { animator ->
            // Get the current blur level from the animator
            val blurLevel = animator.animatedValue as Int
            // Capture the camera preview frame
            val cameraBitmap = captureCameraPreview()
            if (cameraBitmap != null) {
                // Blurring the captured frame using the blurRenderScript function
                val blurredBitmap = blurRenderScript(cameraBitmap, blurLevel)
                // Set the blurred bitmap as the ImageView's image
                blurOverlayImageView.setImageBitmap(blurredBitmap)
            } else {
                Log.e(TAG, "Camera preview bitmap is null")
            }
        }

        // Start the previewAnimator when you start the camera
        previewAnimator.start()
    }

    private fun captureCameraPreview(): Bitmap? {
        val view = cameraPreview.getChildAt(0) as? TextureView
        return view?.bitmap
    }
android android-camera android-drawable android-camerax
1个回答
0
投票

使用 CameraX 应用效果的推荐方法是 CameraEffect API。您需要为此编写 OpenGL 代码。您可以在此处查看代码示例。

在该示例代码中,OpenGlRenderer 包含 OpenGL 代码。复制此代码时,更新片段着色器以应用模糊效果。模糊着色器的示例可以在这个答案中找到。或者,您可以要求 ChatGPT 更新具有模糊效果的示例代码。

© www.soinside.com 2019 - 2024. All rights reserved.