閱讀767 返回首頁    go 阿裏雲 go 技術社區[雲棲]


android 仿qq手寫板塗鴉


以前博客的鏈接:點擊打開鏈接


 

附上關鍵代碼:

MainView.java

  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 代碼:

  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


  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.     }  

最後更新:2017-04-03 12:53:42

  上一篇:go 一張圖讀通Spark源碼
  下一篇:go JLINK 10針J和20針JTAG接口連接方法