欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android画板开发之添加背景和保存画板内容为图片

程序员文章站 2022-08-20 17:29:51
一、绘制背景 绘制背景的方法有两种: 自己利用canvas进行绘制 利用view的自带方法进行绘制 1.1 canvas绘制背景...

一、绘制背景

绘制背景的方法有两种:

  • 自己利用canvas进行绘制
  • 利用view的自带方法进行绘制

Android画板开发之添加背景和保存画板内容为图片

1.1 canvas绘制背景

自己绘制的背景的方法就是在ondraw回调进行绘制的时候,先draw一个背景,再进行draw原来的内容

override fun ondraw(canvas: canvas) {
    super.ondraw(canvas)

    //先绘制颜色作为背景
    canvas.drawcolor(color.black)

    //画出缓存bitmap的内容
    canvas.drawbitmap(mbufferbitmap,0f,0f,null)

  }

1.2 view自带方法

view有setbackground方法,我利用这个方法设置背景setbackgroundresource(r.drawable.bg),这个方法是怎么样执行的,来简单跟踪一下源码,ctrl+鼠标左键 进去这个方法,最终跳到了setbackgrounddrawable,下面是源码(删减了)

public void setbackgrounddrawable(drawable background) {
    computeopaqueflags();

    if (background == mbackground) {
      return;
    }

    boolean requestlayout = false;

    mbackgroundresource = 0;
    ......
    if (background != null) {
      ......


      mbackground = background;


      applybackgroundtint();

      ...
    } else {
      /* remove the background */
      mbackground = null;
      .......
    }

    computeopaqueflags();

    if (requestlayout) {
      requestlayout();
    }

    mbackgroundsizechanged = true;
    invalidate(true);
    invalidateoutline();
  }

可以看到view里面有一个变量mbackground,我们设置的背景会转成drawable然后赋值给它,然后看它是如何绘制的,搜索draw(找到绘制方法,然后看到有一个方法操作了背景drawbackground(canvas),传递了画布过去,这个方法源码:

private void drawbackground(canvas canvas) {
    final drawable background = mbackground;
    if (background == null) {
      return;
    }

    setbackgroundbounds();

    // attempt to use a display list if requested.
    if (canvas.ishardwareaccelerated() && mattachinfo != null
        && mattachinfo.mhardwarerenderer != null) {
      mbackgroundrendernode = getdrawablerendernode(background, mbackgroundrendernode);

      final rendernode rendernode = mbackgroundrendernode;
      if (rendernode != null && rendernode.isvalid()) {
        setbackgroundrendernodeproperties(rendernode);
        ((displaylistcanvas) canvas).drawrendernode(rendernode);
        return;
      }
    }

    final int scrollx = mscrollx;
    final int scrolly = mscrolly;
    if ((scrollx | scrolly) == 0) {
      background.draw(canvas);
    } else {
      canvas.translate(scrollx, scrolly);
      background.draw(canvas);
      canvas.translate(-scrollx, -scrolly);
    }
  }

所以利用自带view的方法,我们可以简单的完成背景的设置,交给view处理即可。

二、 保存画板为图片

保存图片大概有三种方法:

  • 自行保存自己的绘制的bitmap
  • 利用view自带的bitmap
  • 利用view创建bitmap

2.1 自己绘制的bitmap

我们之前的代码 是利用一个bufferbitamp和buffercanvas来进行绘制的,所以,我们的内容就在bufferbitmap,把它保存为图片即可:

 /**
   * 保存图片
   * @param path 保存图片的路径
   */
  fun save(path: string){

    if(!textutils.isempty(path)){

      val f = file(path)
      if(f.exists()){
        f.delete()
      }
      try{
        val out = fileoutputstream(f)
        //以90质量保存到输出到文件输出流
        mbufferbitmap.compress(bitmap.compressformat.jpeg,90,out)

        out.flush()
        out.close()
      }catch (e:exception){
        e.printstacktrace()
      }
    }
  }

但是这种方法,不能保存自行draw绘制的背景。接下来看第二种方法。

2.2 view的drawingcache

在view中,有一个setdrawingcacheenabled方法,这个方法的作用为是开启绘图cache,这个方法也可以增加速度,但是会占用一点内存。所以通常不需要的时候有必要对其进行清理,通过destroydrawingcache或setdrawingcacheenabled(false)实现。

开启了这个方法之后,我们就可以利用getdrawingcache方法来获取当前view绘制的bitmap数据

所以,在view初始化的时候,开启缓存

init {
   mpaint.style = paint.style.stroke //画笔为实心
   mpaint.color = color.red     //颜色
   mpaint.strokecap = paint.cap.round //笔触为圆形
   mpaint.strokewidth = 10f      //画笔大小

    //开启缓存
    isdrawingcacheenabled = true

  }

保存图片的时候,直接获取即可,把上面的mbufferbitmap改为getcachebitmap()即可

/**
 * 利用view自带方法获取bitmap,
 * 前提是开启setdrawingcacheenabled(boolean enabled)
*/
  fun getcachebitmap(): bitmap{

    val bm = drawingcache
    val result = bitmap.createbitmap(bm)
    //销毁build的缓存
    destroydrawingcache()
    return result
  }

2.3 利用view创建bitmap

利用bitmap的createbitmap方法,创建当前view为bitmap。

fun getbitmap(v: view): bitmap{
    val bitmap = bitmap.createbitmap(v.getwidth(), v.getheight(), bitmap.config.argb_8888)
    val canvas = canvas(bitmap)
    v.draw(canvas)
    return bitmap
  }

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