【android开发】RenderScript 实现高斯模糊。

昨天看了下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);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发中,最近任务高斯模糊可以通过以下步骤实现: 1. 首先,在你的布局文件中添加一个FrameLayout,用于显示最近任务列表。 2. 然后,在你的Activity中获取最近任务列表的视图,并将其转换为Bitmap对象。 3. 接下来,使用RenderScript库中的高斯模糊算法对Bitmap对象进行模糊处理。 4. 最后,将处理后的Bitmap对象设置为最近任务列表的背景,从而实现高斯模糊效果。 下面是一些示例代码,展示了如何在Android应用中实现最近任务高斯模糊效果: ``` // 获取最近任务列表的视图 View recentTasksView = getRecentTasksView(); // 将视图转换为Bitmap对象 Bitmap bitmap = Bitmap.createBitmap( recentTasksView.getWidth(), recentTasksView.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); recentTasksView.draw(canvas); // 使用RenderScript库中的高斯模糊算法对Bitmap对象进行模糊处理 bitmap = blurBitmap(bitmap, 25); // 将处理后的Bitmap对象设置为最近任务列表的背景 recentTasksView.setBackground(new BitmapDrawable(getResources(), bitmap)); ``` 其中,blurBitmap()方法可以使用以下代码实现: ``` private Bitmap blurBitmap(Bitmap bitmap, int radius) { RenderScript rs = RenderScript.create(this); Allocation input = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); Allocation output = Allocation.createTyped(rs, input.getType()); ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); blur.setInput(input); blur.setRadius(radius); blur.forEach(output); output.copyTo(bitmap); rs.destroy(); return bitmap; } ``` 需要注意的是,高斯模糊算法需要较高的计算资源,因此在处理大尺寸的Bitmap对象时可能会出现性能问题。为了避免这种情况,可以考虑在后台线程中进行处理,或者使用更加轻量级的模糊算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值