Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android編程實現手繪及保存為圖片的方法(附demo源碼下載)

Android編程實現手繪及保存為圖片的方法(附demo源碼下載)

編輯:關於Android編程

本文實例講述了Android編程實現手繪及保存為圖片的方法。分享給大家供大家參考,具體如下:

運行效果圖預覽:

應 yzuo_08 要求做了此Demo,跟以前那個手寫板Demo不同的是可以將畫布的內容保存為圖片。

附上關鍵代碼:

MainView.java

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

@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

@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程序設計有所幫助。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved