Android:快速位图模糊?

the*_*0ID 33 android image-processing blur convolution

过去三天我一直在寻找内置的硬件加速方式,用android来模拟位图.我偶然发现了某些解决方法,比如缩小位图并再次缩放,但这种方法产生的质量低,不适合我的图像识别要求.我还读到使用着色器或JNI实现卷积是一个很好的方法,但我不能相信Android框架中没有内置的解决方案用于这个非常常见的目的.目前我最终在Java中使用自编写的卷积实现,但它的速度非常慢.我的问题是:

  • 有没有真的没有内置的解决方案在Android框架?
  • 如果没有:在仍然合理的实施和维护复杂性的情况下,加速卷积的最有效方法是什么?我们应该使用JNI,着色器还是完全不同的东西?

the*_*0ID 71

我终于找到了合适的解决方案:

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

但是,关于ScriptIntrinsicBlur该类的文档非常少见,我花了一些时间来确定正确的调用参数.对于blured一个普通的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 /* e.g. 3.f */ );
script.setInput( input );
script.forEach( output );
output.copyTo( photo );
Run Code Online (Sandbox Code Playgroud)

  • RS现在是兼容性lib,renderscript-v8.jar的一部分 (3认同)
  • @ thV0ID:很好的答案.是否有任何方法可以使其向后兼容,也可以在ICS中工作? (2认同)

pat*_*ckf 12

可能最苛刻的要求是实时模糊,这意味着当视图发生变化时,您会模糊不清.在这种情况下,模糊不应超过10秒左右(使一些游戏室达到16ms/60fps)看起来平滑.即使在不那么高端的设备(galaxy s3甚至更慢)上,也可以通过正确的设置实现这种效果.

以下是如何以降低重要性的方式提高性能:

  1. 使用缩小尺寸的图像:这会使像素大幅度模糊.当你想要一个真实的模糊图像时它也适合你.此外,图像加载和内存消耗也大大降低.

  2. 使用的renderScript ScriptIntrinsicBlur -有可能是不作为2014年的一个错误,我经常看到的是,的renderScript上下文不重复使用,但每次创建使用模糊算法更好/更快的Android解决方案.请注意,RenderScript.create(this);在Nexus 5上花费大约20ms,所以你想要避免这种情况.

  3. 重用位图:不要创建不必要的实例并始终使用相同的实例.当你需要非常快速的模糊时,垃圾收集起着重要的作用(收集一些位图需要10-20毫秒).还可以裁剪和模糊您需要的东西.

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

更多提示请参阅我的其他帖子/sf/answers/1618397021/

顺便说一句.我在这个应用程序中做了一个简单的实时模糊:github,Playstore