当前位置: 移动技术网 > IT编程>移动开发>Android > Android RenderScript实现高斯模糊

Android RenderScript实现高斯模糊

2019年07月24日  | 移动技术网IT编程  | 我要评论

卡布西游小白狐,毁灭前夕 倒数救援,j2ee开发

昨天看了下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);
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网