android 仿qq手写板涂鸦

来源:互联网 发布:徐老师的淘宝店有哪些 编辑:程序博客网 时间:2024/05/04 05:04


以前博客的链接:点击打开链接


 

附上关键代码:

MainView.java

[java] view plaincopy
  1. package com.tszy.views;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7.   
  8. import android.content.Context;  
  9. import android.graphics.Bitmap;  
  10. import android.graphics.Bitmap.CompressFormat;  
  11. import android.graphics.Bitmap.Config;  
  12. import android.graphics.Canvas;  
  13. import android.graphics.Color;  
  14. import android.graphics.Paint;  
  15. import android.graphics.Path;  
  16. import android.util.AttributeSet;  
  17. import android.view.MotionEvent;  
  18. import android.view.View;  
  19.   
  20. public class MainView extends View {  
  21.     private Paint paint;  
  22.     private Canvas cacheCanvas;  
  23.     private Bitmap cachebBitmap;  
  24.     private Path path;  
  25.       
  26.     private int clr_bg, clr_fg;  
  27.   
  28.       
  29.     public MainView(Context context, AttributeSet attrs) {  
  30.         super(context, attrs);  
  31.           
  32.         clr_bg = Color.WHITE;  
  33.         clr_fg = Color.CYAN;  
  34.           
  35.         paint = new Paint();  
  36.         paint.setAntiAlias(true); // 抗锯齿  
  37.         paint.setStrokeWidth(3); // 线条宽度  
  38.         paint.setStyle(Paint.Style.STROKE); // 画轮廓  
  39.         paint.setColor(clr_fg); // 颜色  
  40.           
  41.         path = new Path();  
  42.         // 创建一张屏幕大小的位图,作为缓冲  
  43.         cachebBitmap = Bitmap.createBitmap(480800, Config.ARGB_8888);  
  44.         cacheCanvas = new Canvas(cachebBitmap);  
  45.         cacheCanvas.drawColor(clr_bg);  
  46.     }  
  47.   
  48.     public MainView(Context context) {  
  49.         super(context);  
  50.     }  
  51.       
  52.     @Override  
  53.     protected void onDraw(Canvas canvas) {  
  54.         canvas.drawColor(clr_bg);  
  55.   
  56.         // 绘制上一次的,否则不连贯  
  57.         canvas.drawBitmap(cachebBitmap, 00null);  
  58.         canvas.drawPath(path, paint);         
  59.     }  
  60.       
  61.     /** 
  62.      * 清空画布 
  63.      */  
  64.     public void clear() {  
  65.         path.reset();  
  66.         cacheCanvas.drawColor(clr_bg);  
  67.         invalidate();  
  68.     }  
  69.       
  70.     /** 
  71.      * 将画布的内容保存到文件 
  72.      * @param filename 
  73.      * @throws FileNotFoundException 
  74.      */  
  75.     public void saveToFile(String filename) throws FileNotFoundException {  
  76.         File f = new File(filename);  
  77.         if(f.exists())  
  78.             throw new RuntimeException("文件:" + filename + " 已存在!");  
  79.               
  80.         FileOutputStream fos = new FileOutputStream(new File(filename));  
  81.         //将 bitmap 压缩成其他格式的图片数据  
  82.         cachebBitmap.compress(CompressFormat.PNG, 50, fos);  
  83.         try {  
  84.             fos.close();  
  85.         } catch (IOException e) {  
  86.             // TODO Auto-generated catch block  
  87.             e.printStackTrace();  
  88.         }  
  89.     }  
  90.   
  91.     private float cur_x, cur_y;  
  92.     private boolean isMoving;  
  93.     @Override  
  94.     public boolean onTouchEvent(MotionEvent event) {  
  95.         // TODO Auto-generated method stub  
  96.         float x = event.getX();  
  97.         float y = event.getY();  
  98.   
  99.         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.                 // 二次曲线方式绘制  
  113.                 path.quadTo(cur_x, cur_y, x, y);  
  114.                 // 下面这个方法貌似跟上面一样  
  115.                 // path.lineTo(x, y);  
  116.                 cur_x = x;  
  117.                 cur_y = y;  
  118.                 break;  
  119.             }  
  120.   
  121.             case MotionEvent.ACTION_UP : {  
  122.                 // 鼠标弹起保存最后状态  
  123.                 cacheCanvas.drawPath(path, paint);  
  124.                 path.reset();  
  125.                 isMoving = false;  
  126.                 break;  
  127.             }  
  128.         }  
  129.   
  130.         // 通知刷新界面  
  131.         invalidate();  
  132.   
  133.         return true;  
  134.     }  
  135.   
  136. }  

 

Activity 代码:

[java] view plaincopy
  1. @Override  
  2.     public void onClick(View v) {  
  3.         // TODO Auto-generated method stub  
  4.         switch (v.getId()) {  
  5.             case R.id.iv_btn_clear :  
  6.                 view.clear();  
  7.                 break;  
  8.   
  9.             case R.id.iv_btn_save : {  
  10.                 try {  
  11.                     String sdState = Environment.getExternalStorageState(); // 判断sd卡是否存在  
  12.   
  13.                     // 检查SD卡是否可用  
  14.                     if (!sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {  
  15.                         Toast.makeText(this"SD卡未准备好!", Toast.LENGTH_SHORT).show();  
  16.                         break;  
  17.                     }  
  18.   
  19.                     //获取系统图片存储路径  
  20.                     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  21.                     // Make sure the Pictures directory exists.  
  22.                     path.mkdirs();  
  23.                       
  24.                     //根据当前时间生成图片名称  
  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.                     //合成完整路径,注意 / 分隔符  
  32.                     String string = path.getPath() + "/" + name;  
  33.                     view.saveToFile(string);  
  34.                     Toast.makeText(this"保存成功!\n文件保存在:" + string, Toast.LENGTH_LONG).show();  
  35.                 } catch (FileNotFoundException e) {  
  36.                     Toast.makeText(this"保存失败!\n" + e, Toast.LENGTH_LONG).show();  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }  

没什么难度,主要是将Bitmap转PNG图片那里,找了一会发现 Canvas 没有直接或间接保存的方法,刚好这里我使用了双缓冲,另一块画布的内容位图自己创建的,很自然想到将这个画布的位图保存为文件即可。

再查看 Bitmap 有个 compress(CompressFormat format, int quality,OutputStream stream) 方法,很明显将文件输出流传给这个方法就OK


[java] view plaincopy
  1. @Override  
  2.     public void onClick(View v) {  
  3.         // TODO Auto-generated method stub  
  4.         switch (v.getId()) {  
  5.             case R.id.iv_btn_clear :  
  6.                 view.clear();  
  7.                 break;  
  8.   
  9.             case R.id.iv_btn_save : {  
  10.                 try {  
  11.                     String sdState = Environment.getExternalStorageState(); // 判断sd卡是否存在  
  12.   
  13.                     // 检查SD卡是否可用  
  14.                     if (!sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {  
  15.                         Toast.makeText(this"SD卡未准备好!", Toast.LENGTH_SHORT).show();  
  16.                         break;  
  17.                     }  
  18.   
  19.                     //获取系统图片存储路径  
  20.                     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  21.                     // Make sure the Pictures directory exists.  
  22.                     path.mkdirs();  
  23.                       
  24.                     //根据当前时间生成图片名称  
  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.                     //合成完整路径,注意 / 分隔符  
  32.                     String string = path.getPath() + "/" + name;  
  33.                     view.saveToFile(string);  
  34.                     Toast.makeText(this"保存成功!\n文件保存在:" + string, Toast.LENGTH_LONG).show();  
  35.                 } catch (FileNotFoundException e) {  
  36.                     Toast.makeText(this"保存失败!\n" + e, Toast.LENGTH_LONG).show();  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }