Android 手绘 - 支持保存为图片

来源:互联网 发布:java和python的区别 编辑:程序博客网 时间:2024/04/28 07:50

 Android 交流群 110687406 期待贤士

预览

啊,好难看的机器人。。。。尴尬

 

应 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);}@Overrideprotected 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 blocke.printStackTrace();}}private float cur_x, cur_y;private boolean isMoving;@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubfloat 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 代码:

@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (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


@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (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;}}}


源码:源码下载

 

 

原创粉丝点击