私がこれまでに試したこと:
すべてのフレームをビットマップに変換し、 library でぼかして、カメラプレビューの前にある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()
}
}
MainActivity
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()
}
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>
そして残念ながら、それでも遅くなります-3-4 FPS。ぼかしオーバーレイも回転しますが、それは別の問題です。
私はGithubでのテストプロジェクトを作成しました。ここでは、問題をすばやく再現し、最適化の方法を確認できます。あなたのアイデアを楽しみにしています。
[〜#〜] upd [〜#〜]ぼかす前に入力日を縮小することで、パフォーマンスを向上させることができました。これらの変更をテストリポジトリにプッシュしました。今、私はローエンドのデバイスでも本当に良い(15-20 FPS)パフォーマンスを持っていますが、低解像度(たとえばHD)であり、十分ではありませんFHDおよびUHD((8-12 FPS)。
CameraView
を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 で検索できます。
一部のデバイスでは、カメラのプレビューが反転する場合がありますが、それは解決すべきもう1つの問題です。