Div*_*ers 10 camera android blur renderscript
到目前为止我尝试过的:
将每个帧转换为位图,使用库将其模糊并将其放入ImageView相机预览前面.显然太慢了 - 比如1 fps.
然后我开始使用RenderScript,它会模糊每一帧,处理结果应放在TextureView封面相机预览中.
该方法的基本代码和平:
使用BlurFilter
ScriptIntrinsicBlur.create(rs, Element.RGBA_8888(rs)).apply {
setRadius(BLUR_RADIUS)
}
private val yuvToRgb = ScriptIntrinsicYuvToRGB.create(rs, Element.RGBA_8888(rs))
private var surface: SurfaceTexture? = null
private fun setupSurface() {
if (surface != null) {
aBlurOut?.surface = Surface(surface)
}
}
fun reset(width: Int, height: Int) {
aBlurOut?.destroy()
this.width = width
this.height = height
val tbConvIn = Type.Builder(rs, Element.U8(rs))
.setX(width)
.setY(height)
.setYuvFormat(android.graphics.ImageFormat.NV21)
aConvIn = Allocation.createTyped(rs, tbConvIn.create(), Allocation.USAGE_SCRIPT)
val tbConvOut = Type.Builder(rs, Element.RGBA_8888(rs))
.setX(width)
.setY(height)
aConvOut = Allocation.createTyped(rs, tbConvOut.create(), Allocation.USAGE_SCRIPT)
val tbBlurOut = Type.Builder(rs, Element.RGBA_8888(rs))
.setX(width)
.setY(height)
aBlurOut = Allocation.createTyped(rs, tbBlurOut.create(),
Allocation.USAGE_SCRIPT or Allocation.USAGE_IO_OUTPUT)
setupSurface()
}
fun execute(yuv: ByteArray) {
if (surface != null) {
//YUV -> RGB
aConvIn!!.copyFrom(yuv)
yuvToRgb.setInput(aConvIn)
yuvToRgb.forEach(aConvOut)
//RGB -> BLURED RGB
blurRc.setInput(aConvOut)
blurRc.forEach(aBlurOut)
aBlurOut!!.ioSend()
}
}
Run Code Online (Sandbox Code Playgroud)
主要活动
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initQrScanner()
}
override fun onStart() {
super.onStart()
fotoapparat.start()
}
override fun onStop() {
fotoapparat.stop()
super.onStop()
}
private fun initQrScanner() {
val filter = BlurFilter(RenderScript.create(this))
tvWholeOverlay.surfaceTextureListener = filter
fotoapparat = Fotoapparat
.with(this)
.into(cvQrScanner)
.frameProcessor({
if (it.size.width != filter.width || it.size.height != filter.height) {
filter.reset(it.size.width, it.size.height)
}
filter.execute(it.image)
})
.build()
}
Run Code Online (Sandbox Code Playgroud)
activity_main.xml中
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.blur.andrey.blurtest.MainActivity">
<io.fotoapparat.view.CameraView
android:id="@+id/cvQrScanner"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextureView
android:id="@+id/tvWholeOverlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
不幸的是它仍然要慢 - 3-4 FPS.旋转模糊叠加也是如此,但这是另一个问题.
我在Github上创建了测试项目,您可以快速重现问题并检查如何进行优化.期待您的想法.
UPD 我能够在模糊之前缩小输入日期来提高性能.我将这些更改推送到测试回购.现在,我有很好的(15-20 FPS)的性能即使在低端设备,但低分辨率(HD为例),而不是FHD和UHD(不够好(8-12 FPS) .
我认为您可以采取的最佳方法是替换CameraView为a TextureView并将其用作相机预览.你可以在这里轻松找到如何操作的示例https://developer.android.com/reference/android/view/TextureView.html,在这里
https://github.com/dalinaum/TextureViewDemo/blob/master/src/ kr/gdg/android/textureview/CameraActivity.java.
下一步是在您的上使用模糊着色器TextureView.你可以在这里找到一个例子:https:
//github.com/nekocode/blur-using-textureview/blob/master/app/src/main/java/cn/nekocode/blurringview/sample/BlurFilter.java
您可以使用此着色器或查找更漂亮的着色器.
如果您想要一个随时可用的解决方案,您可以查看这个库:https: //github.com/krazykira/VidEffects
它允许您将着色器应用于视频视图,因此,您可以再次使用模糊着色器来实现所需的效果.
此库的示例:https://stackoverflow.com/a/38125734/3286059
编辑
所以我从Nekocode分叉了一个很棒的库,并添加了一个工作模糊过滤器.请看我最近的提交. https://github.com/Dimezis/CameraFilter
正如我所说,TextureView + GL着色器.要启用模糊着色器,请单击右上角的菜单,然后选择相应的选项.
如果您需要更快/更好/更简单的模糊着色器,可以在https://www.shadertoy.com上搜索一个
在某些设备上,您可能会翻转相机预览,但这是另一个需要解决的问题.
| 归档时间: |
|
| 查看次数: |
3026 次 |
| 最近记录: |