移植 StackBlur for Glide & AS 2.2 CMakeLists 的使用

1,392 阅读2分钟
原文链接: gavinliu.cn

StackBlur 是一个快速高斯模糊算法,原作者是由 Mario Klingemann 开发的Javascript版本。Victor Laskin 实现了一个C++多线程版本,Android上我们基于 Victor Laskin 的版本进行JNI移植。
这个算法应用非常广泛 iOS 上 Camera+ 也是用的这套算法,还有CUDA版本等…

这里我们可以直接借用 android-stackblur 的代码,注意这个版本并不支持带透明度的图片,且不要使用多线程来处理图片。

CMakeLists

Android Studio 2.2以上的版本支持使用CMake来编译JNI了,具体操作可以参考官方文档

developer.android.com/studio/proj…

流程没什么难点,官网上有的就不再赘述,对于没有接触过CMake的人来说,编写 CMakeLists 文件是很懵逼的事情,想要完整学完CMake,学习曲线还是蛮陡峭的,下面就是移植后的 CMakeLists 文件。以后自己编写其他的 CMakeLists 参照例子依葫芦画瓢即可。

CMakeLists.txt
# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.
cmake_minimum_required(VERSION 3.4.1)
add_library( StackBlur
             SHARED
             src/main/cpp/StackBlur.c )
# 从ndk中寻找库,StackBlur.c 使用了这些库所以需要找出来。
# 下面的代码的含义是找到 log 库,命名为 log-lib
find_library( log-lib
              log )
find_library( m-lib
              m )
find_library( jnigraphics-lib
              jnigraphics )
target_link_libraries( StackBlur
                       ${log-lib}
                       ${m-lib}
                       ${jnigraphics-lib} )

集成 glide

glide 是一个优秀的图片加载库,具有强大的可扩展性,对于图片的处理Gilde使用 Transformation 进行图片的转换功能,我们就只需要实现一个模糊功能的 Transformation 即可。

GlideStackBlur.java
public class GlideStackBlur extends BitmapTransformation {
    private TintColorGenerator mTintColorGenerator;
    public GlideStackBlur(Context context) {
        super(context);
    }
    public GlideStackBlur(Context context, TintColorGenerator tintColorGenerator) {
        super(context);
        mTintColorGenerator = tintColorGenerator;
    }
    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        if (toTransform != null) {
            long startTime = System.currentTimeMillis();
            BlurUtils blurManager = new BlurUtils(toTransform);
            Bitmap blur = blurManager.process(40);
            final Bitmap result = Bitmap.createBitmap(blur.getWidth(), blur.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setFilterBitmap(true);
            canvas.drawBitmap(blur, 0, 0, paint);
            blurManager.recycle();
            if (BuildConfig.DEBUG) {
                Log.d("GlideStackBlur", outWidth + "," + outHeight + "  Time: " + (System.currentTimeMillis() - startTime));
            }
            return result;
        }
        return null;
    }
    @Override
    public String getId() {
        String id = "cn.gavinliu.android.lib.glide.stackblur.GlideStackBlur";
        if (mTintColorGenerator != null) {
            id += mTintColorGenerator.getId();
        }
        return id;
    }
}

Glide.with(this).load(url)
        .transform(new GlideStackBlur(this))
        .into(imageView);

扩展染色功能

使用 ColorFilter 功能可以在图片上在叠加一个颜色。

...
if (mTintColorGenerator != null) {
    int color = mTintColorGenerator.generate(toTransform);
    PorterDuffColorFilter colorFilter = new PorterDuffColorFilter((color), PorterDuff.Mode.SRC_OVER);
    paint.setColorFilter(colorFilter);
}
...
Glide.with(this).load(url)
        .transform(new GlideStackBlur(this, new TintColorGenerator() {
            @Override
            public int generate(Bitmap bitmap) {
                // You can generate dynamic color
                return 0x803F51B5;
            }
            @Override
            public String getId() {
                return ".TintColorGenerator";
            }
        }))
        .into(imageView);

查看图片

源码

github.com/gavinliu/gl…