Android RenderScript实现高斯模糊
昨天看了下renderscript的官方文档,发现renderscript这厮有点牛逼。无意中发现scriptintrinsic这个抽象类,有些很有用的子类。其中有个子类叫scriptintrinsicblur类,大致就是将图片实现高斯模糊。
scriptintrinsic的申明:
scriptintrinsicblur类的申明:
加上结合着看了下sdk中的samples,自己写了个高斯模糊。
( sample的具体位置为:
sdk目录/samples/android-19/renderscript/renderscriptintrinsic/renderscriptintrinsicsample/
)。
先上图。效果如下:
【注意!! 开始之前,我们需要导入需要的支持包。
支持包的具体路径为: sdk目录/buildtools/任意一个版本号/renderscript/lib/renderscript-v8.jar
另外:为了防止出现有的机型兼容问题,最好将renderscript-v8.jar同目录下的packaged目录下的所有库也一并拷贝到lib文件夹下】
例如:
好了。开始写代码。。
1、先申明常用成员变量。
private seekbar blurseekbar;//拖动条 private imageview img_blur;//显示模糊后bitmap的imageview //原bitmap和高斯模糊后的bitmap private bitmap bitmap_original, bitmap_blur; //高斯模糊处理的asynctask private renderscripttask mlatesttask = null; //renderscript 对象(google的高性能并行计算类,他可以利用设备的gpu/cpu等计算资源) private renderscript mrs; //下面是两个renderscript的传入参数对象 private allocation minallocation; private allocation moutallocation; //高斯模糊处理实例 private scriptintrinsicblur mscriptblur;
2、加载两份bitmap,并初始化高斯模糊相关的对象。
@override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); blurseekbar = (seekbar) findviewbyid(r.id.aty_main_seekbar); img_blur = (imageview) findviewbyid(r.id.aty_main_img_blur); bitmap_original = loadbitmap(r.drawable.meet_entry_guide_3); // 复制一份 bitmap_blur = bitmap.createbitmap(bitmap_original.getwidth(), bitmap_original.getheight(), bitmap_original.getconfig()); createblurescript(); setseekbarlistening();//为seekbar设置拖拽监听 } /** * helper to load bitmap from resource */ private bitmap loadbitmap(int resource) { final bitmapfactory.options options = new bitmapfactory.options(); options.inpreferredconfig = bitmap.config.argb_8888; return bitmapfactory.decoderesource(getresources(), resource, options); } /** * 创建script */ private void createblurescript() { mrs = renderscript.create(this); minallocation = allocation.createfrombitmap(mrs, bitmap_original); moutallocation = allocation.createfrombitmap(mrs, bitmap_blur); /* * create intrinsics. renderscript has built-in features such as blur, * convolve filter etc. these intrinsics are handy for specific * operations without writing renderscript kernel. in the sample, it's * creating blur, convolve and matrix intrinsics. */ mscriptblur = scriptintrinsicblur.create(mrs, element.u8_4(mrs)); }
3、完成高斯模糊处理代码。
private void performfilter(allocation inallocation, allocation outallocation, bitmap bitmapout, float value) { /* * 设置模糊程度。范围在0~25之间。否则会出错 */ mscriptblur.setradius(value); /* * invoke filter kernel */ mscriptblur.setinput(inallocation); mscriptblur.foreach(outallocation); outallocation.copyto(bitmapout); }
4、将处理后的bitmap设置到imageview中。
// request ui update img_blur.setimagebitmap(bitmap_blur); img_blur.invalidate();
基本工作也就完成了。剩下就是代码的相互调用了。
【 总 结 】
其实总起来,使用renderscript进行高斯模糊主要是分为三步:
1、创建并初始化需要的对象(初始化一次就ok)。
mrs = renderscript.create(this); mscriptblur = scriptintrinsicblur.create(mrs, element.u8_4(mrs)); //renderscript的输入和输出参数对象 minallocation = allocation.createfrombitmap(mrs, bitmap_original); moutallocation = allocation.createfrombitmap(mrs, bitmap_blur);
2、执行高斯模糊,并将结果拷贝出来。
/* * 设置模糊程度。范围在0~25之间。否则会出错(这个也可以只设置一次) */ mscriptblur.setradius(value); /* * invoke filter kernel */ mscriptblur.setinput(inallocation); mscriptblur.foreach(outallocation); //将结果拷贝出来,拷贝到bitmapout对象中 outallocation.copyto(bitmapout);
3、回收renderscript对象
mrs.destory(); mrs = null;
文章到此结束。
按照惯例:下面是我的完整的代码实现。
public class mainactivity extends activity { private seekbar blurseekbar; private imageview img_blur; private bitmap bitmap_original, bitmap_blur; private renderscripttask mlatesttask = null; private renderscript mrs; private allocation minallocation; private allocation moutallocation; private scriptintrinsicblur mscriptblur; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); blurseekbar = (seekbar) findviewbyid(r.id.aty_main_seekbar); img_blur = (imageview) findviewbyid(r.id.aty_main_img_blur); bitmap_original = loadbitmap(r.drawable.meet_entry_guide_3); // 复制一份 bitmap_blur = bitmap.createbitmap(bitmap_original.getwidth(), bitmap_original.getheight(), bitmap_original.getconfig()); createblurescript(); setseekbarlistening(); } /** * 设置seekbar的监听 */ private void setseekbarlistening() { blurseekbar.setonseekbarchangelistener(new onseekbarchangelistener() { @override public void onstoptrackingtouch(seekbar seekbar) { } @override public void onstarttrackingtouch(seekbar seekbar) { } @override public void onprogresschanged(seekbar seekbar, int progress, boolean fromuser) { updateimage(progress); } }); } /** * 创建script */ private void createblurescript() { mrs = renderscript.create(this); minallocation = allocation.createfrombitmap(mrs, bitmap_original); moutallocation = allocation.createfrombitmap(mrs, bitmap_blur); /* * create intrinsics. renderscript has built-in features such as blur, * convolve filter etc. these intrinsics are handy for specific * operations without writing renderscript kernel. in the sample, it's * creating blur, convolve and matrix intrinsics. */ mscriptblur = scriptintrinsicblur.create(mrs, element.u8_4(mrs)); } private void performfilter(allocation inallocation, allocation outallocation, bitmap bitmapout, float value) { /* * set blur kernel size */ mscriptblur.setradius(value); /* * invoke filter kernel */ mscriptblur.setinput(inallocation); mscriptblur.foreach(outallocation); outallocation.copyto(bitmapout); } /* * in the asynctask, it invokes renderscript intrinsics to do a filtering. * after the filtering is done, an operation blocks at allication.copyto() * in asynctask thread. once all operation is finished at onpostexecute() in * ui thread, it can invalidate and update imageview ui. */ private class renderscripttask extends asynctask<float, integer, integer> { boolean issued = false; protected integer doinbackground(float... values) { if (iscancelled() == false) { issued = true; performfilter(minallocation, moutallocation, bitmap_blur, values[0]); } return 0; } void updateview(integer result) { // request ui update img_blur.setimagebitmap(bitmap_blur); img_blur.invalidate(); } protected void onpostexecute(integer result) { updateview(result); } protected void oncancelled(integer result) { if (issued) { updateview(result); } } } /* * invoke asynchtask and cancel previous task. when asynctasks are piled up * (typically in slow device with heavy kernel), only the latest (and * already started) task invokes renderscript operation. */ private void updateimage(int progress) { float f = getblureparam(progress); if (mlatesttask != null) mlatesttask.cancel(false); mlatesttask = new renderscripttask(); mlatesttask.execute(f); } /** * 模糊的值在1 ~ 25之间 * * @param progress * seekbar的进度值(0 ~ 100) * @return 模糊值 */ private float getblureparam(int progress) { final float max = 25.0f; final float min = 1.f; return (float) ((max - min) * (progress / 100.0) + min); } /** * helper to load bitmap from resource */ private bitmap loadbitmap(int resource) { final bitmapfactory.options options = new bitmapfactory.options(); options.inpreferredconfig = bitmap.config.argb_8888; return bitmapfactory.decoderesource(getresources(), resource, options); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Java基础教程之实现接口