CameraX:如何设置 PreviewView 的背景?
CameraX: How to set background of PreviewView?
默认情况下,翻转相机时,屏幕会空白一段时间,直到相机启动。我想稍微改变一下这种行为。
我希望最后一帧模糊并设置,直到创建新的绑定 Camera 实例。我尝试将 getBitmap()
与 BitmapDrawable
和 setBackground()
一起使用,但这似乎并没有真正起作用(屏幕仍然是空白)。
代码:
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
中的变化
默认情况下,翻转相机时,屏幕会空白一段时间,直到相机启动。我想稍微改变一下这种行为。
我希望最后一帧模糊并设置,直到创建新的绑定 Camera 实例。我尝试将 getBitmap()
与 BitmapDrawable
和 setBackground()
一起使用,但这似乎并没有真正起作用(屏幕仍然是空白)。
代码:
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
中的变化