Android:快速位图模糊?

我一直在寻找过去三天内置的,硬件加速的Android模糊位图的方式。 我偶然发现了一些缩小位图的方法,并且再次将其扩展,但是这种方法产生的质量不佳,不适合我的图像识别要求。 我还看到,使用着色器或JNI实现卷积是一个好的方法,但我不能相信在Android框架中没有内置的解决scheme来实现这个共同的目的。 目前我已经完成了一个自编写的Java卷积实现,但是速度很慢。 我的问题是:

  • Android框架中是否真的没有内置的解决scheme
  • 如果没有的话:用合理的实现和维护的复杂性来加速卷积的最有效的方法是什么? 我们可以使用JNI,着色器还是完全不同的东西?

Solutions Collecting From Web of "Android:快速位图模糊?"

我终于find了合适的解决scheme:

  • RenderScript允许执行大量的计算,这些计算透明地扩展到执行设备上可用的所有内核。 我已经得出结论,就性能和实现复杂性的合理平衡而言,这是比JNI或着色器更好的方法。
  • 从API级别17开始,可以从API获得ScriptIntrinsicBlur类。 这正是我一直在寻找的,即高层次的硬件加速高斯模糊实现。
  • ScriptIntrinsicBlur现在是支持Froyo和更高版本(API> 8)的android支持库(v8)的一部分。 支持RenderScript库的android开发者博客文章有一些关于如何使用它的基本技巧。

但是, ScriptIntrinsicBlur类中的文档非常罕见,我花了一些时间来计算正确的调用参数。 为了使普通的ARGB_8888型位图命名为photo ,在这里他们是:

 final RenderScript rs = RenderScript.create( myAndroidContext ); final Allocation input = Allocation.createFromBitmap( rs, photo, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT ); final Allocation output = Allocation.createTyped( rs, input.getType() ); final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create( rs, Element.U8_4( rs ) ); script.setRadius( myBlurRadius /* eg 3.f */ ); script.setInput( input ); script.forEach( output ); output.copyTo( photo ); 

可能最苛刻的要求是实时模糊,这意味着当视图改变时您会模糊生活。 在这种情况下,模糊不应该花费10ms左右的时间(让16ms / 60fps的游戏室看起来很平滑)。 即使不是那么高端的设备(galaxy s3,甚至更慢),也可以通过正确的设置来达到这个效果。

以下是如何提高性能的重要性:

  1. 使用缩小的图像:这会使像素变得非常模糊。 当你想要一个真正的模糊图像,它也适用于你。 图像加载和内存消耗也大大降低。

  2. 使用Renderscript ScriptIntrinsicBlur – 自2014年以来,Android中可能没有更好/更快的解决scheme。我经常看到的一个错误是,Renderscript上下文没有被重用,而是在每次使用模糊algorithm时创build。 请注意RenderScript.create(this); Nexus 5需要大约20ms,所以你想避免这个。

  3. 重用位图:不要创build不必要的实例并始终使用相同的实例。 当你需要真正快速的模糊时,垃圾收集扮演着重要的angular色(收集一些位图需要10-20毫秒的时间)。 也裁剪和模糊只有你需要的东西。

  4. 对于一个活的模糊,可能是因为上下文切换,不可能在另一个线程中模糊(即使使用线程池),只有主线程足够快以保持视图更新及时,线程我看到滞后100-300ms

在更多的提示看到我的其他职位在这里https://stackoverflow.com/a/23119957/774398

顺便说一句。 我在这个应用程序做了一个简单的生活模糊: github , Playstore