图片模糊解决方案

  • JAVA算法
  • JNI调用C算法
  • RenderScript

最近在项目中用到了图片模糊,模糊方案用了开源的JAVA算法FastBlur,其实效果并不是很好,有两个明显的缺陷,一个是临时内存过大,另一个是耗时长。因为这两个坎,使得模糊半径不能太大,效果不是很好(模糊半径越大,模糊效果越好,但计算量也会增大)。在我的映像中,这种计算量较大的算法用JNI是比较好的,c在计算速度上有天然的优势,朝着这个目的我在网上找开源的c语言模糊算法,没想到还收货了一个惊喜,那就是RenderScript。

JAVA算法

我选的模糊半径是25,1080P的图片,用项目中的算法进行测试.(项目中的模糊半径是10).

android progressbar模糊 安卓模糊_Blur


3864毫秒。

JNI调用C算法

这种办法的效率确实高,但缺点就是麻烦,还要编写makefile文件和JNI接口,还要用NDK编译c的源文件。还好网上已经有开源的NDK项目,只要少加修改就可以了。

需要注意的是这里对Bitmap进行了处理,所以要依赖 ljnigraphics模块。

android progressbar模糊 安卓模糊_RenderScri_02

运行结果不出所料,同样的图片,同样的模糊半径,速度是前者的4倍。

android progressbar模糊 安卓模糊_RenderScri_03


1195毫秒。

RenderScript

RenderScript is a framework for running computationally intensive tasks at high performance on Android. RenderScript is primarily oriented for use with data-parallel computation, although serial workloads can benefit as well. The RenderScript runtime parallelizes work across processors available on a device, such as multi-core CPUs and GPUs. This allows you to focus on expressing algorithms rather than scheduling work. RenderScript is especially useful for applications performing image processing, computational photography, or computer vision.

这是Google官方对RenderScript的解释,大概意思是RS是一个高性能的计算框架,他的主要方向是并行计算,他可以在多核cpu和gpu的设备上发挥优势。最后一句说明,他主要应用于图像处理、摄影、和视觉。哦?这么牛逼?

经过查阅,发现RS自带了一个模糊算法,当然你也可以自己写RS脚本去实现。

android progressbar模糊 安卓模糊_JAVA_04

实现起来还是比较容易的,只要设置几个参数即可。看下效果:

android progressbar模糊 安卓模糊_Blur_05


125毫秒

同样半径也是25,速度相当恐怖。

总结

方法

速度

JAVA

3853ms

JNI

1195ms

RS

125ms

综合来看:
JAVA算法兼容性最好,但性能太差。

JNI性能中等,但占内存较大,编译后,每个动态链接库有十几K,每个平台都编译的话内存可能会过百K,对于现在寸K寸金的环境下,100多K去优化一个点值得商榷。

RS性能最好,但兼容性不好,Android 4.2以后才可以使用,虽然官方在V8中提供了兼容包,但还是有很多不兼容的问题。不过目前Andorid已经迈向7.0,4.2的机型也越来越少,在项目中增加API判断,4.2以上用RS,4.2以下用之前的算法,在我看来这是最好的选择吧。