CameraX:如何设置 PreviewView 的背景?

CameraX: How to set background of PreviewView?

默认情况下,翻转相机时,屏幕会空白一段时间,直到相机启动。我想稍微改变一下这种行为。

我希望最后一帧模糊并设置,直到创建新的绑定 Camera 实例。我尝试将 getBitmap()BitmapDrawablesetBackground() 一起使用,但这似乎并没有真正起作用(屏幕仍然是空白)。

代码:

    void startCamera(final boolean forced){

        if(!forced && camera!=null) return;

        Preview preview = new Preview.Builder()
                .build();

        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(this.cameraSelector)
                .build();

        ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                .build();

        ImageCapture.Builder builder = new ImageCapture.Builder();

        final ImageCapture imageCapture = builder
                .setTargetRotation(this.getWindowManager().getDefaultDisplay().getRotation())
                .build();

        Bitmap b = mPreviewView.getBitmap();

        preview.setSurfaceProvider(mPreviewView.getSurfaceProvider());

        mPreviewView.setBackground(new BitmapDrawable(getResources(), b));

        // Unbind/close all other camera(s) [if any]
        cameraProvider.unbindAll();

        // Get a camera instance bound to the lifecycle of this activity
        camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis, imageCapture);

        // Focus camera on touch/tap
        mPreviewView.setOnTouchListener(this);

        start_auto_focus();
    }

模糊位图功能

    private Bitmap blurRenderScript(Bitmap smallBitmap, int radius) {

        final float defaultBitmapScale = 0.1f;

        int width  = Math.round(smallBitmap.getWidth() * defaultBitmapScale);
        int height = Math.round(smallBitmap.getHeight() * defaultBitmapScale);

        Bitmap inputBitmap  = Bitmap.createScaledBitmap(smallBitmap, width, height, false);
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);

        RenderScript renderScript = RenderScript.create(this);
        ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
        Allocation tmpIn = Allocation.createFromBitmap(renderScript, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(renderScript, outputBitmap);
        theIntrinsic.setRadius(radius);
        theIntrinsic.setInput(tmpIn);
        theIntrinsic.forEach(tmpOut);
        tmpOut.copyTo(outputBitmap);

        return outputBitmap;
    }

有什么方法可以覆盖黑屏行为吗?

我刚刚解决了你的问题,方法是使用 this BlurImageView 作为预览叠加层,使用值动画器自动更改模糊级别,并在预览为 [=34= 时使用 PreviewView 回调]可见。

设置 ValueAnimator:(用于自动更改渐进模糊动画的模糊级别)

// Initializing the preview animator with value to blur
val previewAnimator = ValueAnimator.ofInt(6, 12, 18, 24, 25)
// Setting animation duration
previewAnimator.duration = 2000
// Adding listener for every value update of the animation
previewAnimator.addUpdateListener { animator ->
    // Blurring the preview when it is not visible
    blurOverlayImageView.setBlur(animator.animatedValue as Int)
}
// Adding action that is invoked on animation start
previewAnimator.doOnStart {
    // Setting the current preview frame as the canvas bitmap
    blurOverlayImageView.setImageBitmap(previewView.bitmap)
}
// Adding action that is invoked on animation cancel
previewAnimator.doOnCancel {
    // Removing the blurred preview to reveal the current actual preview
    blurOverlayImageView.setImageBitmap(null)
}

*动画的时长是2秒,因为2秒比预览重新开始的时间要长,所以这样动画还没有做完就可以取消了,因为做完之后无法取消,移除最后一张预览图的回调不会触发

*每次重启相机前先启动previewAnimator

*blurOverlayImageView - 预览叠加模糊图像视图

预览可见性回调:

查看 answer 我在 Android CameraX 讨论组中的问题,了解如何为预览可见性设置回调 - 使用:previewView.previewStreamState.observe(previewObserver)

*previewObserver - 一个 Observer 对象,用于观察 PreviewView.StreamState

中的变化