本文实例讲述了android编程实现手绘及保存为图片的方法。分享给大家供大家参考,具体如下:
运行效果图预览:
应 yzuo_08 要求做了此demo,跟以前那个手写板demo不同的是可以将画布的内容保存为图片。
附上关键代码:
mainview.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
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 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@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程序设计有所帮助。