天天看点

Android实现动态高斯模糊

网上有一把分享,不过我还是打算搞一下,嘻嘻嘻。。。先上核心代码,后说明

private Bitmap blur(Bitmap bitmap, float radius) {
        Bitmap output = Bitmap.createBitmap(bitmap); // 创建输出图片
        RenderScript rs = RenderScript.create(getActivity()); // 构建一个RenderScript渲染对象
        ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
        // 创建高斯模糊脚本
        Allocation allIn = Allocation.createFromBitmap(rs, bitmap); // 开辟输入内存
        Allocation allOut = Allocation.createFromBitmap(rs, output); // 开辟输出内存
        gaussianBlue.setRadius(radius); // 设置模糊半径,(0.0f,25.0f]
        gaussianBlue.setInput(allIn); // 设置输入内存
        gaussianBlue.forEach(allOut); // 模糊编码,并将内存填入输出内存
        allOut.copyTo(output); // 将输出内存编码为Bitmap,图片大小必须注意,可以预先将图片压缩
        rs.destroy(); // 关闭RenderScript对象,API>=23则使用rs.releaseAllContexts()
        return output;
    }
           

RenderScript渲染脚本是安卓平台进行高性能计算的框架,该类使用了大量的native方法,我现在着实看不懂,只会调用其方法。在此mark一下。这个blur类只要输入目标图片和想要模糊的程度参数就可以了。

动态实现高斯模糊如果是通过blur类动态修改模糊度的话,会设计大量的计算,结果就是效果很卡顿。

这里有一个巧妙的实现,就是将两张图片叠加在一起,底下的那张图片事先就已经实现了模糊度,然后动态修改上面的那张图片的透明度。

<LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="300dp">

                <ImageView
                    android:scaleType="fitCenter"
                    android:id="@+id/fragment3_iv1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

                <ImageView
                    android:id="@+id/fragment_vi2"
                    android:src="@drawable/beatui"
                    android:scaleType="fitCenter"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

            </FrameLayout>

            <SeekBar
                android:id="@+id/fragment_seekBar"
                android:layout_width="match_parent"
                android:layout_height="50dp" />

</LinearLayout>
           
iv=findViewById(R.id.fragment3_iv1);
        iv2=findViewById(R.id.fragment_vi2);
        seekBar=findViewById(R.id.fragment_seekBar);
        seekBar.setMax(255);
   
        final Bitmap res=BitmapFactory.decodeResource(getResources(),R.drawable.beatui);
        iv.setImageBitmap(blur(res,25f));
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                iv2.setImageAlpha(255-progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
           

然后通过seekbar动态就该图片的透明度就实现动态高斯模糊了。学习是一个过程,坚持!