本文实例讲述了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程序设计有所帮助。