首页 > 系统 > Android > 正文

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

2020-04-11 11:10:03
字体:
来源:转载
供稿:网友

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

运行效果图预览:

应 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程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表