项目中需要运用到毛玻璃的效果。经过搜索查阅,踩了一些坑,找到了一条暂时可行的办法。

  其中,核心的控件是使用RenderScript这个类,这个类属于jni类,在较低版本的Android系统中,是不具备它的相关方法的。所以我们只能使用support.v8里面的类。然而,support.v8并没有默认地放在新建工程中,因此我们需要自己去添加。

  第一步:将D:\AndroidSdk\build-tools\23.0.1\renderscript\lib\packaged 目录下的armeabi-v7a和x86文件夹置于工程的libs路径中

  

 

  第二步:在build.gradle中写脚本编译这两个.so文件

    task nativeLibsToJar(type: Zip, description: "create a jar archive of the native libs") {
        destinationDir file("$projectDir/libs")
        baseName "Native_Libs2"
        extension "jar"
        from fileTree(dir: "libs", include: "**/*.so")
        into "lib"
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn(nativeLibsToJar)
    }

 

  第三步:Rebuild Project

 

  第四步:添加刚刚编译的jar包Native_Libs2

  

  第五步:毛玻璃效果的方法

    private void blur(Bitmap overlay, View view, int radius) {

        RenderScript rs = RenderScript.create(this);
        Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);
        ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement());
        blur.setInput(overlayAlloc);
        blur.setRadius(radius);
        blur.forEach(overlayAlloc);
        overlayAlloc.copyTo(overlay);
        view.setBackground(new BitmapDrawable(getResources(), overlay));
        rs.destroy();
    }

 

  PS:这个方法中radius为图片模糊的粒度。我们进入setRadius方法中,可以看到

    public void setRadius(float radius) {
        if(radius > 0.0F && radius <= 25.0F) {
            this.setVar(0, radius);
        } else {
            throw new RSIllegalArgumentException("Radius out of range (0 < r <= 25).");
        }
    }

  radius最大只能是25.0

  我猜想,在设计这个方法时,开发人员也考虑到这个方法是一个时间复杂度比较高的方法,尤其在大图片,需要较大模糊程度的情况下,会有很大的概率出现性能问题,甚至OOM。

  那么,如果我们需要比25更模糊的情况,或是,有一张较大的图片需要模糊化时,该怎么办呢?

  常用的方法,即是,将原来需要模糊化的图片先缩小,再模糊化,最后再显示。经过一轮缩小之后,系统会自动将一些象素点综合成一个,经过模糊再放大,获得的模糊程度将高于直接模糊化的程度。

Done!

 

posted on 2015-11-22 20:35  Fishbonell  阅读(798)  评论(0编辑  收藏  举报