Android GPUImage setImage 和 getBitmapWithFilterApplied 导致屏幕闪烁
Android GPUImage setImage and getBitmapWithFilterApplied cause screen to flicker
我一直在使用这个 github 作为我的代码的开始:https://github.com/xizhang/camerax-gpuimage
该代码是一种显示带有 GPUImage 滤镜的相机视图的方法。
我还希望能够分析应用了过滤器的位图以获得一些分析(图像中的百分比 red/green/blue)。
我已成功向用户显示默认相机视图以及我创建的过滤器。
通过注释掉 setImage 代码行,我已经能够获得过滤图像的分析结果,但是当我尝试同时执行这两项操作时,屏幕会闪烁。我更改了 StartCameraIfReady 函数以获取过滤后的图像,如下所示:
@SuppressLint("UnsafeExperimentalUsageError")
private fun startCameraIfReady() {
if (!isPermissionsGranted() || cameraProvider == null) {
return;
}
val imageAnalysis = ImageAnalysis.Builder().setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build()
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer {
var bitmap = allocateBitmapIfNecessary(it.width, it.height)
converter.yuvToRgb(it.image!!, bitmap)
it.close()
gpuImageView.post {
// These two lines conflict causing the screen to flicker
// I can comment out one or the other and it works great
// But running both at the same time causes issues
gpuImageView.gpuImage.setImage(bitmap)
val filtered = gpuImageView.gpuImage.getBitmapWithFilterApplied(bitmap)
/*
Analyze the filtered image...
Print details about image here
*/
}
})
cameraProvider!!.unbindAll()
cameraProvider!!.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, imageAnalysis)
}
当我尝试获取过滤后的位图时,它似乎与 setImage 代码行冲突并导致屏幕闪烁,如下面的视频所示。我可以向用户显示预览,也可以分析图像,但不能同时进行。我已经尝试 运行 它们同步以及每个都在它们自己的后台线程上。我也尝试添加另一个 Image Analyzer 并将其绑定到相机生命周期(一个用于预览,另一个用于获取过滤后的位图),屏幕仍然闪烁但不那么频繁了。
<blockquote class="imgur-embed-pub" lang="en" data-id="a/mXeuEhe" ><a href="//imgur.com/a/mXeuEhe">screenRocord</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
如果您要获得应用滤镜的位图,您甚至不需要 GPUImageView。您可以只获取位图,然后将其设置在常规 ImageView 上。这就是您的分析仪的样子:
ImageAnalysis.Analyzer {
var bitmap = allocateBitmapIfNecessary(it.width, it.height)
converter.yuvToRgb(it.image!!, bitmap)
it.close()
val filteredBitmap = gpuImage.getBitmapWithFilterApplied(bitmap)
regularImageView.post {
regularImageView.setImageBitmap(filteredBitmap)
}
}
请注意,原始 GitHub 示例效率低下,上面的示例更糟,因为它们在将输出反馈给 GPU 之前将其转换为位图。为了获得预览流参数的最佳性能,请参阅 CameraX's core test app 了解如何通过 OpenGL 访问预览 Surface。
我一直在使用这个 github 作为我的代码的开始:https://github.com/xizhang/camerax-gpuimage
该代码是一种显示带有 GPUImage 滤镜的相机视图的方法。 我还希望能够分析应用了过滤器的位图以获得一些分析(图像中的百分比 red/green/blue)。
我已成功向用户显示默认相机视图以及我创建的过滤器。
通过注释掉 setImage 代码行,我已经能够获得过滤图像的分析结果,但是当我尝试同时执行这两项操作时,屏幕会闪烁。我更改了 StartCameraIfReady 函数以获取过滤后的图像,如下所示:
@SuppressLint("UnsafeExperimentalUsageError")
private fun startCameraIfReady() {
if (!isPermissionsGranted() || cameraProvider == null) {
return;
}
val imageAnalysis = ImageAnalysis.Builder().setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build()
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer {
var bitmap = allocateBitmapIfNecessary(it.width, it.height)
converter.yuvToRgb(it.image!!, bitmap)
it.close()
gpuImageView.post {
// These two lines conflict causing the screen to flicker
// I can comment out one or the other and it works great
// But running both at the same time causes issues
gpuImageView.gpuImage.setImage(bitmap)
val filtered = gpuImageView.gpuImage.getBitmapWithFilterApplied(bitmap)
/*
Analyze the filtered image...
Print details about image here
*/
}
})
cameraProvider!!.unbindAll()
cameraProvider!!.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, imageAnalysis)
}
当我尝试获取过滤后的位图时,它似乎与 setImage 代码行冲突并导致屏幕闪烁,如下面的视频所示。我可以向用户显示预览,也可以分析图像,但不能同时进行。我已经尝试 运行 它们同步以及每个都在它们自己的后台线程上。我也尝试添加另一个 Image Analyzer 并将其绑定到相机生命周期(一个用于预览,另一个用于获取过滤后的位图),屏幕仍然闪烁但不那么频繁了。
<blockquote class="imgur-embed-pub" lang="en" data-id="a/mXeuEhe" ><a href="//imgur.com/a/mXeuEhe">screenRocord</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
如果您要获得应用滤镜的位图,您甚至不需要 GPUImageView。您可以只获取位图,然后将其设置在常规 ImageView 上。这就是您的分析仪的样子:
ImageAnalysis.Analyzer {
var bitmap = allocateBitmapIfNecessary(it.width, it.height)
converter.yuvToRgb(it.image!!, bitmap)
it.close()
val filteredBitmap = gpuImage.getBitmapWithFilterApplied(bitmap)
regularImageView.post {
regularImageView.setImageBitmap(filteredBitmap)
}
}
请注意,原始 GitHub 示例效率低下,上面的示例更糟,因为它们在将输出反馈给 GPU 之前将其转换为位图。为了获得预览流参数的最佳性能,请参阅 CameraX's core test app 了解如何通过 OpenGL 访问预览 Surface。