Android TV 动态设置背景的高斯模糊

940 阅读3分钟

导语:

用过小米电视的小伙伴都知道,高斯模糊在小米上得到了广泛的运用,比如小米电视的设置界面.那么什么是高斯模糊,怎么样做高斯模糊,这篇文章给你揭晓. ###什么是高斯模糊 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。

高斯模糊给人的感觉是一层蒙版,这样的话不会让背景过于单调.

###Android中实现高斯模糊的方式 在Adnroid 中,现在常用的图片高斯模糊技术有三种:RenderScript 、fastBlur、对RenderScript和fastBlur的优化.简书上有一篇文章介绍了Android对高斯模糊的实现Android 图片高斯模糊解决方案,这里讲的比较详细,具体原理可以参考这里. ###AndroidTv中如何实现背景的高斯模糊. 在文章首的图片实现了dialog背景的高斯模糊,实现背景的高斯模糊需要以下几个步骤.

  1. 对背景截图
   /**
     * 获取整个窗口的截图
     *
     * @param context
     * @return
     */
    @SuppressLint("NewApi")
    private static Bitmap captureScreen(Activity context) {
        if (view != null){
            //清空缓冲
            view.destroyDrawingCache();
        }
        view = context.getWindow().getDecorView();

        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        if (bmp == null) {
            return null;
        }

        bmp.setHasAlpha(false);
        bmp.prepareToDraw();

        return bmp;
    }
  1. 对截图进行高斯模糊化
/**
     * 返回高斯模糊的图片效果
     *
     * @param context
     * @param bitmap
     * @param radius
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static Bitmap blur(Context context, Bitmap bitmap, float radius) {
        // 创建输出图片
        Bitmap output = Bitmap.createBitmap(bitmap);
        // 构建一个RenderScript对象
        RenderScript rs = RenderScript.create(context);
        // 创建高斯模糊脚本
        ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        // 创建用于输入的脚本类型
        Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
        // 创建用于输出的脚本类型
        Allocation allOut = Allocation.createFromBitmhttps://github.com/songwenju/CustomTvRecyclerView.ap(rs, output);
        // 设置模糊半径,范围0f<radius<=25f
        gaussianBlue.setRadius(radius);
        // 设置输入脚本类型
        gaussianBlue.setInput(allIn);
        // 执行高斯模糊算法,并将结果填入输出脚本类型中
        gaussianBlue.forEach(allOut);
        // 将输出内存编码为Bitmap,图片大小必须注意
        allOut.copyTo(output);
        // 关闭RenderScript对象,API>=23则使用rs.releaseAllContexts()
        rs.destroy();
        return output;
    }
  1. 将bitmap转为drawable并设置给view
 /**
     * 获得背景的高斯模糊图 drawable
     *
     * @param context
     * @param radius
     * @return
     */
    public static Drawable getBackBlurDrawable(Context context, float radius) {
        return new BitmapDrawable(context.getResources(), getBackBlurBitmap(context, radius));
    }

  View view = findViewById(R.id.layout_dialog);
  view.setBackground(mBackDrawable);

这样就对图片做成了高斯模糊.

动态设置背景

我写的demo是监听menu键去弹出dialog,在处理逻辑的时候发现截图不变.原来写的截图逻辑是:


/**
    * 获取整个窗口的截图
    *
    * @param context
    * @return
    */
   @SuppressLint("NewApi")
   private static Bitmap captureScreen(Activity context) {
     
       View view = context.getWindow().getDecorView();

       view.setDrawingCacheEnabled(true);
       view.buildDrawingCache();
       Bitmap bmp = view.getDrawingCache();
       if (bmp == null) {
           return null;
       }

       bmp.setHasAlpha(false);
       bmp.prepareToDraw();

       return bmp;
   }

后来通过查阅资料发现这里需要把上一个view销毁调才可以,添加以下的代码:

 if (view != null){
            //清空缓冲
            view.destroyDrawingCache();
}

这样的话就实现了动态的功能,在多个界面设置高斯模糊.

代码已经上传到github上了CustomTvRecyclerView.


这篇文章介绍了为view动态设置高斯模糊的背景,希望对你有帮助.