Android RenderScript实现高斯模糊

Phemia ·
更新时间:2024-09-21
· 503 次阅读

昨天看了下RenderScript的官方文档,发现RenderScript这厮有点牛逼。无意中发现ScriptIntrinsic这个抽象类,有些很有用的子类。其中有个子类叫ScriptIntrinsicBlur类,大致就是将图片实现高斯模糊。

ScriptIntrinsic的申明:

ScriptIntrinsic申明

ScriptIntrinsicBlur类的申明:

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); } } 您可能感兴趣的文章:Android实现动态高斯模糊效果示例代码Android 实现图片模糊、高斯模糊、毛玻璃效果的三种方法Android关于Glide的使用(高斯模糊、加载监听、圆角图片)Android RenderScript高斯模糊Android 实现高斯模糊效果且兼容低版本Android 动态高斯模糊效果教程Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)Android实现动态高斯模糊效果Android图片特效:黑白特效、圆角效果、高斯模糊Android实现图片转高斯模糊以及高斯模糊布局



高斯 高斯模糊 Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号