Draw a very ugly robot...
Add the key code:
MainView. java
001
Package com. tszy. views;
002
003
Import java. io. File;
004
Import java. io. FileNotFoundException;
005
Import java. io. FileOutputStream;
006
Import java. io. IOException;
007
008
Import android. content. Context;
009
Import android. graphics. Bitmap;
010
Import android. graphics. Bitmap. CompressFormat;
011
Import android. graphics. Bitmap. Config;
012
Import android. graphics. Canvas;
013
Import android. graphics. Color;
014
Import android. graphics. Paint;
015
Import android. graphics. Path;
016
Import android. util. AttributeSet;
017
Import android. view. MotionEvent;
018
Import android. view. View;
019
020
Public class MainView extends View {
021
Private Paint paint;
022
Private Canvas cacheCanvas;
023
Private Bitmap cachebBitmap;
024
Private Path path;
025
026
Private int clr_bg, clr_fg;
027
028
029
Public MainView (Context context, AttributeSet attrs ){
030
Super (context, attrs );
031
032
Clr_bg = Color. WHITE;
033
Clr_fg = Color. CYAN;
034
035
Paint = new Paint ();
036
Paint. setAntiAlias (true); // anti-aliasing
037
Paint. setStrokeWidth (3); // line width
038
Paint. setStyle (Paint. Style. STROKE); // draw the outline
039
Paint. setColor (clr_fg); // color
040
041
Path = new Path ();
042
// Create a screen size bitmap as a buffer
043
CachebBitmap = Bitmap. createBitmap (480,800, Config. ARGB_8888 );
044
CacheCanvas = new Canvas (cachebBitmap );
045
CacheCanvas. drawColor (clr_bg );
046
}
047
048
Public MainView (Context context ){
049
Super (context );
050
}
051
052
@ Override
053
Protected void onDraw (Canvas canvas ){
054
Canvas. drawColor (clr_bg );
055
056
// Draw the last image; otherwise, the image is inconsistent.
057
Canvas. drawBitmap (cachebBitmap, 0, 0, null );
058
Canvas. drawPath (path, paint );
059
}
060
061
/**
062
* Clear the canvas
063
*/
064
Public void clear (){
065
Path. reset ();
066
CacheCanvas. drawColor (clr_bg );
067
Invalidate ();
068
}
069
070
/**
071
* Save the content of the canvas to a file.
072
* @ Param filename
073
* @ Throws FileNotFoundException
074
*/
075
Public void saveToFile (String filename) throws FileNotFoundException {
076
File f = new File (filename );
077
If (f. exists ())
078
Throw new RuntimeException ("file:" + filename + "already exists! ");
079
080
FileOutputStream fos = new FileOutputStream (new File (filename ));
081
// Compress bitmap into image data of other formats
082
CachebBitmap. compress (CompressFormat. PNG, 50, fos );
083
Try {
084
Fos. close ();
085
} Catch (IOException e ){
086
// TODO Auto-generated catch block
087
E. printStackTrace ();
088
}
089
}
090
091
Private float cur_x, cur_y;
092
Private boolean isMoving;
093
@ Override
094
Public boolean onTouchEvent (MotionEvent event ){
095
// TODO Auto-generated method stub
096
Float x = event. getX ();
097
Float y = event. getY ();
098
099
Switch (event. getAction ()){
100
Case MotionEvent. ACTION_DOWN :{
101
Cur_x = x;
102
Cur_y = y;
103
Path. moveTo (cur_x, cur_y );
104
IsMoving = true;
105
Break;
106
}
107
108
Case MotionEvent. ACTION_MOVE :{
109
If (! IsMoving)
110
Break;
111
112
// Draw the quadratic curve
113
Path. quadTo (cur_x, cur_y, x, y );
114
// The method below seems to be the same as above
115
// Path. lineTo (x, y );
116
Cur_x = x;
117
Cur_y = y;
118
Break;
119
}
120
121
Case MotionEvent. ACTION_UP :{
122
// Hover the mouse to save the final state
123
CacheCanvas. drawPath (path, paint );
124
Path. reset ();
125
IsMoving = false;
126
Break;
127
}
128
}
129
130
// Notification refresh Interface
131
Invalidate ();
132
133
Return true;
134
}
135
136
}
Activity Code:
01
@ Override
02
Public void onClick (View v ){
03
// TODO Auto-generated method stub
04
Switch (v. getId ()){
05
Case R. id. iv_btn_clear:
06
View. clear ();
07
Break;
08
09
Case R. id. iv_btn_save :{
10
Try {
11
String sdState = Environment. getExternalStorageState (); // determines whether the SD card exists.
12
13
// Check whether the SD card is available
14
If (! SdState. equals (android. OS. Environment. MEDIA_MOUNTED )){
15
Toast. makeText (this, "the SD card is not ready! ", Toast. LENGTH_SHORT). show ();
16
Break;
17
}
18
19
// Obtain the system image storage path
20
File path = Environment. getExternalStoragePublicDirectory (Environment. DIRECTORY_PICTURES );
21
// Make sure the Pictures directory exists.
22
Path. mkdirs ();
23
24
// Generate an image name based on the current time
25
Calendar c = Calendar. getInstance ();
26
String name = ""
27
+ C. get (Calendar. YEAR) + c. get (Calendar. MONTH) + c. get (Calendar. DAY_OF_MONTH)
28
+ C. get (Calendar. HOUR_OF_DAY) + c. get (Calendar. MINUTE) + c. get (Calendar. SECOND)
29
+ ". Png ";
30
31
// Synthesize the complete path, note/delimiter
32
String string = path. getPath () + "/" + name;
33
View. saveToFile (string );
34
Toast. makeText (this, "saved successfully! \ N files are saved in: "+ string, Toast. LENGTH_LONG). show ();
35
} Catch (FileNotFoundException e ){
36
Toast. makeText (this, "failed to save! \ N "+ e, Toast. LENGTH_LONG). show ();
37
}
38
Break;
39
}
40
}
41
}
There is no difficulty. It mainly refers to converting Bitmap to a PNG image. After looking for a while, I found that the Canvas is not directly or indirectly saved. I used double buffering here, the content bitmap of another canvas is created by yourself. Naturally, you can save the bitmap of this canvas as a file.
Check that Bitmap has a compress (CompressFormat format, int quality, OutputStream stream) method. It is obvious that it is OK to pass the file output to this method.