失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android 开源 高斯模糊_android高斯模糊特效

android 开源 高斯模糊_android高斯模糊特效

时间:2021-12-30 12:41:07

相关推荐

android 开源 高斯模糊_android高斯模糊特效

参考文献:/huli870715/article/details/39378349

/grp0916/article/details/50494712

1. RenderScript

RenderScript是由Android3.0引入,用来在Android

上编写高性能代码的一种语言(使用C99标准)。RenderScript有类似于CUDA的Compute

API用于计算,配置和设置相对比较容易。最终的运行速度实际上要比胜过于NDK的实现方式,需要编写的代码比较少。而RenderScript最适合用于做3D的用户界面或高性能计算任务。目前android内置API。实例代码如下:

privatevoid applyBlur() {

image.getViewTreeObserver().addOnPreDrawListener(newViewTreeObserver.OnPreDrawListener()

{

@Override

publicbooleanonPreDraw()

{

image.getViewTreeObserver().removeOnPreDrawListener(this);

image.buildDrawingCache();

Bitmap bmp = image.getDrawingCache();

blur(bmp,

text,true);

returntrue;

}

});

}

privatevoid

blur(Bitmap bkg, View view) {

long

startMs = System.currentTimeMillis();

float

radius = 20;

Bitmap

overlay =

Bitmap.createBitmap((int)(view.getMeasuredWidth()),(int)(view.getMeasuredHeight()),

Bitmap.Config.ARGB_8888);

Canvas

canvas =new

Canvas(overlay);

canvas.translate(-view.getLeft(),-view.getTop());

canvas.drawBitmap(bkg, 0,

0,null);

RenderScript

rs =

RenderScript.create(SecondActivity.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();

}

当ImageView开始加载背景图时,取出它的drawableCache,进行blur处理,Gaussian

blur的主要逻辑在blur函数中。对于在Java中使用RenderScript,对应到我们的代码,步骤为:

初始化一个RenderScript Context.

至少创建一个Allocation对象用于存储需要处理的数据.

创建compute

kernel的实例,本例中是内置的ScriptIntrinsicBlur对象.

设置ScriptIntrinsicBlur实例的相关属性,包括Allocation,

radius等.

开始blur操作,对应(forEach).

将blur后的结果拷贝回bitmap中。

总结:

由于Android假设每一帧的处理时间不能超过16ms(屏幕刷新频率60fps),因此,若在主线程里执行RenderScript操作,可能会造成卡顿现象。最好的方式是将其放入AsyncTask中执行。

2. FastBlur

由于高斯模糊归根结底是像素点的操作,也许在java层可以直接操作像素点来进行模糊化处理。google一下,果不其然,一个名为stackblur的开源项目提供了名为fastBlur的方法在java层直接进行高斯模糊处理。/kikoso/android-stackblur

这里,仅仅是把RenderScript相关的操作换成了FastBlur提供的api。

privatevoidblur(Bitmap

bkg, View view) {

Bitmap

overlay =

Bitmap.createBitmap((int)(view.getMeasuredWidth()),(int)(view.getMeasuredHeight()),Bitmap.Config.ARGB_8888);

Canvas

canvas =new

Canvas(overlay);

canvas.translate(-view.getLeft(),-view.getTop());

canvas.drawBitmap(bkg, 0,

0,null);

overlay =

FastBlur.doBlur(overlay,

(int)radius,true);

view.setBackground(new

BitmapDrawable(getResources(),overlay));

}

结论:效果很好,但是花费时间多出好多,很难接受……。

那我们继续改进:先通过缩小图片,使其丢失一些像素点,接着进行模糊化处理,然后再放大到原来尺寸。由于图片缩小后再进行模糊处理,需要处理的像素点和半径都变小,从而使得模糊处理速度加快。

privatevoidblur(Bitmap

bkg, View view) {

long

startMs = System.currentTimeMillis();

float

radius = 2;

float

scaleFactor = 8;

Bitmap

overlay =

Bitmap.createBitmap((int)(view.getMeasuredWidth()/scaleFactor),(int)(view.getMeasuredHeight()/scaleFactor),Bitmap.Config.ARGB_8888);

Canvas

canvas =new

Canvas(overlay);

canvas.translate(-view.getLeft()/scaleFactor,-view.getTop()/scaleFactor);

canvas.scale(1 / scaleFactor, 1 /scaleFactor);

Paint paint

=new

Paint();

paint.setFlags(Paint.FILTER_BITMAP_FLAG);

canvas.drawBitmap(bkg, 0, 0, paint);

overlay =

FastBlur.doBlur(overlay,

(int)radius,true);

view.setBackground(new

BitmapDrawable(getResources(),overlay));

statusText.setText("cost " +

(System.currentTimeMillis()- startMs)

+"ms");

}

代码所创建的bitmap为原图的1/8大小,接着,同样使用fastBlur来进行模糊化处理,最后再为textview设置背景,此时,背景图会自动放大到初始大小。注意,由于这里进行了缩放,radius的取值也要比之前小得多(这里将原始取值除以8得到近似值2)

结论:效果一样,处理速度却快得惊人。它相对于renderScript方案来说,节省了拷贝bitmap到Allocation中,处理完后再拷贝回来的时间开销。

但是,由于FastBlur是将整个bitmap拷贝到一个临时的buffer中进行像素点操作,因此,它不适合处理一些过大的背景图

如果觉得《android 开源 高斯模糊_android高斯模糊特效》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。