Android 手繪 - 支持保存爲圖片

CSDN只看帖不會貼,哎!java

發來 OSC 看看咯!android


OK 先看看效果canvas


畫了一個很是難看的機器人。。。ide

附上關鍵代碼:this

MainView.javaspa

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

@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 沒有直接或間接保存的方法,恰好這裏我使用了雙緩衝,另外一塊畫布的內容位圖本身建立的,很天然想到將這個畫布的位圖保存爲文件便可。code

再查看 Bitmap 有個 compress(CompressFormat format, int quality,OutputStream stream) 方法,很明顯將文件輸出流傳給這個方法就OKorm

源碼:源碼下載 blog

相關文章
相關標籤/搜索