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

Android编程实现手绘及保存为图片的方法(附demo源码下载)

程序员文章站 2023-12-15 15:37:58
本文实例讲述了android编程实现手绘及保存为图片的方法。分享给大家供大家参考,具体如下: 运行效果图预览: 应 yzuo_08 要求做了此demo,跟以前那个手...

本文实例讲述了android编程实现手绘及保存为图片的方法。分享给大家供大家参考,具体如下:

运行效果图预览:

Android编程实现手绘及保存为图片的方法(附demo源码下载)

应 yzuo_08 要求做了此demo,跟以前那个手写板demo不同的是可以将画布的内容保存为图片。

附上关键代码:

mainview.java

package com.tszy.views; 
import java.io.file; 
import java.io.filenotfoundexception; 
import java.io.fileoutputstream; 
import java.io.ioexception; 
import android.content.context; 
import android.graphics.bitmap; 
import android.graphics.bitmap.compressformat; 
import android.graphics.bitmap.config; 
import android.graphics.canvas; 
import android.graphics.color; 
import android.graphics.paint; 
import android.graphics.path; 
import android.util.attributeset; 
import android.view.motionevent; 
import android.view.view; 
public class mainview extends view { 
 private paint paint; 
 private canvas cachecanvas; 
 private bitmap cachebbitmap; 
 private path path; 
 private int clr_bg, clr_fg; 
 public mainview(context context, attributeset attrs) { 
  super(context, attrs); 
  clr_bg = color.white; 
  clr_fg = color.cyan; 
  paint = new paint(); 
  paint.setantialias(true); // 抗锯齿 
  paint.setstrokewidth(3); // 线条宽度 
  paint.setstyle(paint.style.stroke); // 画轮廓 
  paint.setcolor(clr_fg); // 颜色 
  path = new path(); 
  // 创建一张屏幕大小的位图,作为缓冲 
  cachebbitmap = bitmap.createbitmap(480, 800, config.argb_8888); 
  cachecanvas = new canvas(cachebbitmap); 
  cachecanvas.drawcolor(clr_bg); 
 } 
 public mainview(context context) { 
  super(context); 
 } 
 @override 
 protected void ondraw(canvas canvas) { 
  canvas.drawcolor(clr_bg); 
  // 绘制上一次的,否则不连贯 
  canvas.drawbitmap(cachebbitmap, 0, 0, null); 
  canvas.drawpath(path, paint);
 } 
 /** 
  * 清空画布 
  */ 
 public void clear() { 
  path.reset(); 
  cachecanvas.drawcolor(clr_bg); 
  invalidate(); 
 } 
 /** 
  * 将画布的内容保存到文件 
  * @param filename 
  * @throws filenotfoundexception 
  */ 
 public void savetofile(string filename) throws filenotfoundexception { 
  file f = new file(filename); 
  if(f.exists()) 
   throw new runtimeexception("文件:" + filename + " 已存在!"); 
  fileoutputstream fos = new fileoutputstream(new file(filename)); 
  //将 bitmap 压缩成其他格式的图片数据 
  cachebbitmap.compress(compressformat.png, 50, fos); 
  try { 
   fos.close(); 
  } catch (ioexception e) { 
   // todo auto-generated catch block 
   e.printstacktrace(); 
  } 
 } 
 private float cur_x, cur_y; 
 private boolean ismoving; 
 @override 
 public boolean ontouchevent(motionevent event) { 
  // todo auto-generated method stub 
  float x = event.getx(); 
  float y = event.gety(); 
  switch (event.getaction()) { 
   case motionevent.action_down : { 
    cur_x = x; 
    cur_y = y; 
    path.moveto(cur_x, cur_y); 
    ismoving = true; 
    break; 
   } 
   case motionevent.action_move : { 
    if (!ismoving) 
     break; 
    // 二次曲线方式绘制 
    path.quadto(cur_x, cur_y, x, y); 
    // 下面这个方法貌似跟上面一样 
    // path.lineto(x, y); 
    cur_x = x; 
    cur_y = y; 
    break; 
   } 
   case motionevent.action_up : { 
    // 鼠标弹起保存最后状态 
    cachecanvas.drawpath(path, paint); 
    path.reset(); 
    ismoving = false; 
    break; 
   } 
  } 
  // 通知刷新界面 
  invalidate(); 
  return true; 
 } 
}

activity 代码:

@override 
public void onclick(view v) { 
  // todo auto-generated method stub 
  switch (v.getid()) { 
   case r.id.iv_btn_clear : 
    view.clear(); 
    break; 
   case r.id.iv_btn_save : { 
    try { 
     string sdstate = environment.getexternalstoragestate(); // 判断sd卡是否存在 
     // 检查sd卡是否可用 
     if (!sdstate.equals(android.os.environment.media_mounted)) { 
      toast.maketext(this, "sd卡未准备好!", toast.length_short).show(); 
      break; 
     } 
     //获取系统图片存储路径 
     file path = environment.getexternalstoragepublicdirectory(environment.directory_pictures); 
     // make sure the pictures directory exists. 
     path.mkdirs(); 
     //根据当前时间生成图片名称 
     calendar c = calendar.getinstance(); 
     string name = "" 
       + c.get(calendar.year) + c.get(calendar.month) + c.get(calendar.day_of_month) 
       + c.get(calendar.hour_of_day) + c.get(calendar.minute) + c.get(calendar.second) 
        + ".png"; 
     //合成完整路径,注意 / 分隔符 
     string string = path.getpath() + "/" + name; 
     view.savetofile(string); 
     toast.maketext(this, "保存成功!\n文件保存在:" + string, toast.length_long).show(); 
    } catch (filenotfoundexception e) { 
     toast.maketext(this, "保存失败!\n" + e, toast.length_long).show(); 
    } 
    break; 
   } 
  } 
}

没什么难度,主要是将bitmap转png图片那里,找了一会发现 canvas 没有直接或间接保存的方法,刚好这里我使用了双缓冲,另一块画布的内容位图自己创建的,很自然想到将这个画布的位图保存为文件即可。

再查看 bitmap 有个 compress(compressformat format, int quality,outputstream stream) 方法,很明显将文件输出流传给这个方法就ok

@override 
public void onclick(view v) { 
  // todo auto-generated method stub 
  switch (v.getid()) { 
   case r.id.iv_btn_clear : 
    view.clear(); 
    break; 
   case r.id.iv_btn_save : { 
    try { 
     string sdstate = environment.getexternalstoragestate(); // 判断sd卡是否存在 
     // 检查sd卡是否可用 
     if (!sdstate.equals(android.os.environment.media_mounted)) {
      toast.maketext(this, "sd卡未准备好!", toast.length_short).show(); 
      break; 
     } 
     //获取系统图片存储路径 
     file path = environment.getexternalstoragepublicdirectory(environment.directory_pictures); 
     // make sure the pictures directory exists. 
     path.mkdirs(); 
     //根据当前时间生成图片名称 
     calendar c = calendar.getinstance(); 
     string name = "" 
       + c.get(calendar.year) + c.get(calendar.month) + c.get(calendar.day_of_month) 
       + c.get(calendar.hour_of_day) + c.get(calendar.minute) + c.get(calendar.second) 
        + ".png"; 
     //合成完整路径,注意 / 分隔符 
     string string = path.getpath() + "/" + name; 
     view.savetofile(string); 
     toast.maketext(this, "保存成功!\n文件保存在:" + string, toast.length_long).show(); 
    } catch (filenotfoundexception e) { 
     toast.maketext(this, "保存失败!\n" + e, toast.length_long).show(); 
    } 
    break; 
   } 
  } 
}

完整实例代码点击此处本站下载

希望本文所述对大家android程序设计有所帮助。

上一篇:

下一篇: