android 实时高斯模糊 毛玻璃效果

在找遍了网上所有关于实时高斯模糊的效果,并没有直接现成的例子,所以自己东拼西凑,在加上自己的改动,终于实现出来了
如图:
效果图

本示例是在ConvenientBanner这个开源库demo上改的,自己写一个浪费时间,直接拿来用

在找遍了所有高斯模糊的算法代码后,发现stackblur的java实现是最快的

先说一下大致思路,非常简单。模糊的区域其实是一张Imageview,当视图发生变化,在滚动的时候,截取Imgeview下面的视图,进行模糊处理,然后放在Imageview上,下面说一下详细细节:

因为要实时监听banner控件在发生变化,所以我用到了这个方法

ViewTreeObserver.OnScrollChangedListener

见名知意,当发生滚动的时候,进行回调。那给谁设置监听器呢?谁放生变化就给谁设置监听器

convenientBanner = (ConvenientBanner) findViewById(R.id.convenientBanner);
observer = convenientBanner.getViewTreeObserver();
observer.addOnScrollChangedListener(listener);

这个convenientBanner就是一个Linerlayout的封装,就是现实滑动图片的控件

接下来改截取被Imageview盖住的区域图片了

ViewTreeObserver.OnScrollChangedListener listener = new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
convenientBanner.setDrawingCacheEnabled(true);
convenientBanner.buildDrawingCache();
Bitmap bitmap = convenientBanner.getDrawingCache();//截取区域视图

        int x = (int) imageView.getX();
        int y = (int) imageView.getY();
        int bitmapX = bitmap.getWidth();
        int bitmapY = bitmap.getHeight();
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap,x,y,bitmapX-x,bitmapY-y);

        if (bitmap != null){
            blur(bitmap1,imageView,8);//模糊处理
        }
        bitmap1.recycle();
        convenientBanner.setDrawingCacheEnabled(false);//清除缓存
    }
};</cdoe>

Bitmap bitmap = convenientBanner.getDrawingCache();//截取区域视图
是获取Imageview盖住的区域图片,但为什么要用convenientBanner,因为视图是显示在convenientBanner视图树里头的,通过计算
int x = (int) imageView.getX();
int y = (int) imageView.getY();
int bitmapX = bitmap.getWidth();
int bitmapY = bitmap.getHeight();
Bitmap bitmap1 = Bitmap.createBitmap(bitmap,x,y,bitmapX-x,bitmapY-y);

进行截取,createBitmap的第2个跟第3个参数是距离屏幕左跟上的距离,第4个跟第5个参数是裁剪后的宽高,千万别设置错了,数值绝对不能大于bitmapX ,bitmapY ,会抛出异常
然后调用blur(bitmap1,imageView,8);//模糊处理方法进行处理,这个8是模糊半径
blur的代码为:
private void blur(Bitmap bkg, ImageView view, float radius) {
int scaleFactor = 8;
if (overlay != null){
overlay.recycle();
}
overlay = Bitmap.createScaledBitmap(bkg, bkg.getWidth() / scaleFactor, bkg.getHeight() / scaleFactor, false);
overlay = process.blur(overlay, radius);//高斯模糊
view.setImageBitmap(overlay);
}

因为高斯模糊效率的快慢取决于图片的像素点的多少,所以我进行了8倍的缩小,
为什么调用了createScaledBitmap而不是compress呢,因为compress是对成像质量做处理,并不能真正意义上的减少像素点。
这里缩放为8,模糊半径为8,缩放的值越大,你半径就要要设的越大,但不能设置比1小,要不就没效果了。模糊半径约小,图片效果越清晰。如果图片压缩的太小,像素块就会看起来越来越大,如果模糊半径越小,即使模糊了,也会有像素块的效果,所以我调成两个8感觉好不错,你们回去也可以自己调。

其实看起来还是很简单的。

ConvenientBanner地址为:https://github.com/saiwu-bigkoo/Android-ConvenientBanner
stackblur地址为:https://github.com/kikoso/android-stackblur
还有一个很好很快的blur库,但是不够灵活,地址为:https://github.com/wasabeef/Blurry
demo地址为http://pan.baidu.com/s/1pKkhK8N我用的是百度云盘的,csdn上传太慢了
以后只要有时间,会坚持写博客的,希望有错误的地方多多指正.
感谢大家阅读。

  • 12
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
要实现高斯模糊背景的对话框,可以使用 Android 的 DialogFragment 和 RenderScript 实现。以下是大致的步骤: 1. 在布局文件中定义对话框的 UI,注意要为对话框添加一个半透明的背景。 2. 创建一个继承自 DialogFragment 的类,并在其中实现 onCreateDialog() 方法。 3. 在 onCreateDialog() 方法中,使用 RenderScript 创建一个高斯模糊的 Bitmap,并将其设置为对话框背景。 4. 在对话框显示时,使用 DialogFragment.show() 方法显示对话框。 以下是示例代码: ```java public class BlurDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // 创建一个对话框 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.dialog_layout, null); builder.setView(view); // 创建一个 RenderScript 对象 RenderScript rs = RenderScript.create(getActivity()); // 加载图片资源 Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.background); // 创建一个高斯模糊的 Bitmap Bitmap blurredBitmap = image.copy(Bitmap.Config.ARGB_8888, true); Allocation input = Allocation.createFromBitmap(rs, image); Allocation output = Allocation.createFromBitmap(rs, blurredBitmap); ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setInput(input); script.setRadius(25.f); script.forEach(output); output.copyTo(blurredBitmap); // 将高斯模糊的 Bitmap 设置为对话框背景 view.setBackground(new BitmapDrawable(getResources(), blurredBitmap)); return builder.create(); } } ``` 要实现毛玻璃效果的对话框,可以使用 Android 的 DialogFragment 和自定义控件实现。以下是大致的步骤: 1. 在布局文件中定义对话框的 UI,包括一个用于显示毛玻璃效果的自定义控件。 2. 创建一个继承自 DialogFragment 的类,并在其中实现 onCreateDialog() 方法。 3. 在 onCreateDialog() 方法中,创建一个自定义控件的实例,并将其添加到对话框的 UI 中。 4. 在对话框显示时,使用 DialogFragment.show() 方法显示对话框。 以下是示例代码: ```java public class GlassDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // 创建一个对话框 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.dialog_layout, null); builder.setView(view); // 创建一个自定义控件 GlassView glassView = new GlassView(getActivity()); ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); glassView.setLayoutParams(layoutParams); // 将自定义控件添加到对话框的 UI 中 FrameLayout frameLayout = view.findViewById(R.id.frame_layout); frameLayout.addView(glassView); return builder.create(); } } ``` 其中 GlassView 是一个自定义控件,用于显示毛玻璃效果。以下是示例代码: ```java public class GlassView extends View { private Paint paint = new Paint(); private Bitmap bitmap; public GlassView(Context context) { super(context); init(); } public GlassView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public GlassView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { // 加载图片资源 bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background); // 设置画笔透明度 paint.setAlpha(100); } @Override protected void onDraw(Canvas canvas) { // 创建一个缩小的 Bitmap,用于实现毛玻璃效果 Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 10, bitmap.getHeight() / 10, false); // 将缩小的 Bitmap 放大,实现模糊效果 Bitmap blurredBitmap = Bitmap.createScaledBitmap(scaledBitmap, getWidth(), getHeight(), false); // 绘制模糊的 Bitmap canvas.drawBitmap(blurredBitmap, 0, 0, paint); } } ``` 注意:以上代码只是示例代码,实际上还需要根据具体情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值