Android 手寫簽名和裁剪

效果圖:



主要代碼:

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

@SuppressLint("ClickableViewAccessibility")
public class SignView extends View {

	private Canvas mCanvas;
	private Paint mPaint;
	private Path mPath;
	private Bitmap mBitmap;
	private Paint mBitmapPaint;
	private int mX;
	private int mY;
	private int mScreenWidth;
	private int mScreenHeight;

	private Matrix matrix;

	private Point mPoint;

	private int maxX;
	private int maxY;
	private int minY;
	private int minX;

	private int pading=20;
	private boolean isCaculater;

	public SignView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
		initScreen(context);
		init();

	}


	public SignView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		// TODO Auto-generated constructor stub
	}

	public SignView(Context context) {
		this(context, null);
		// TODO Auto-generated constructor stub
	}

	private void initScreen(Context context) {
		// TODO Auto-generated method stub
		WindowManager manager=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics outMetrics=new DisplayMetrics();
		manager.getDefaultDisplay().getMetrics(outMetrics);
		mScreenWidth=outMetrics.widthPixels;
		mScreenHeight=outMetrics.heightPixels;
	}

	private void init() {
		// TODO Auto-generated method stub
		mBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.ARGB_8888);
		mCanvas = new Canvas(mBitmap);
		mPath = new Path();
		mBitmapPaint = new Paint(Paint.DITHER_FLAG);

		mPaint = new Paint();  
		mPaint.setAntiAlias(true); 
		mPaint.setDither(true);    
		mPaint.setColor(Color.parseColor("#404040"));  
		mPaint.setStyle(Paint.Style.STROKE);  
		mPaint.setStrokeJoin(Paint.Join.ROUND);  
		mPaint.setStrokeCap(Paint.Cap.ROUND);  
		mPaint.setStrokeWidth(10); 

		matrix=new Matrix();
		mPoint=new Point();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);

		canvas.drawBitmap(mBitmap, matrix, mBitmapPaint);
		canvas.drawPath(mPath, mPaint);
	}


	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub

		int x = (int) event.getX();
		int y = (int) event.getY();
		mPoint.x=x;
		mPoint.y=y;

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			if(!isCaculater){
				isCaculater=true;
				maxX=x;
				maxY=y;
				minX=x;
				minY=y;
			}else{
				caculater(mPoint);
			}
			startDraw(x, y);

			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			caculater(mPoint);

			moveDraw(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			upDraw();
			invalidate();
			break;
		}
		return true;
	}

	private void upDraw() {
		// TODO Auto-generated method stub
		mPath.lineTo(mX, mY);
		mCanvas.drawPath(mPath, mPaint);
		mPath.reset();
	}

	private void moveDraw(int x, int y) {
		// TODO Auto-generated method stub
		int dx = Math.abs(x - mX);
		int dy = Math.abs(y - mY);

		if (dx >= 2 || dy >= 2) {

			mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);// 二次方貝塞爾曲線
			mX = x;
			mY = y;
		}
	}

	private void startDraw(int x, int y) {
		// TODO Auto-generated method stub
		mPath.reset();
		mPath.moveTo(x, y);
		mX = x;
		mY = y;
	}

	/**
	 * 得到指定寬高的手繪圖(繪製區域)
	 * @param width
	 * @param height
	 * @return
	 */
	public Bitmap getSignBitmap(int width,int height){
		Bitmap retBitmap = Bitmap.createBitmap(mBitmap, minX-pading,minY-pading, maxX-minX+pading, maxY-minY+pading, matrix, true);
		retBitmap=zoomImg(retBitmap, width, height);
		return retBitmap;
	}

	public void caculater(Point b){
		maxX=compareMaxX(b);
		maxY=compareMaxY(b);
		minX=compareMinX(b);
		minY=compareMinY(b);
	}
	public int compareMaxX(Point b){
		return maxX>b.x?maxX:b.x;
	}
	public int compareMaxY(Point b){
		return maxY>b.y?maxY:b.y;
	}
	public int compareMinX(Point b){
		return minX<b.x?minX:b.x;
	}
	public int compareMinY(Point b){
		return minY<b.y?minY:b.y;
	}

	/** 
	 *  處理圖片  
	 * @param bm 所要轉換的bitmap 
	 * @param newWidth新的寬 
	 * @param newHeight新的高   
	 * @return 指定寬高的bitmap 
	 */ 
	public Bitmap zoomImg(Bitmap bm, int newWidth ,int newHeight){   
		// 獲得圖片的寬高   
		int width = bm.getWidth();   
		int height = bm.getHeight();   
		// 計算縮放比例   
		float scaleWidth = ((float) newWidth) / width;   
		float scaleHeight = ((float) newHeight) / height;   
		// 取得想要縮放的matrix參數   
		Matrix matrix = new Matrix();   
		matrix.postScale(scaleWidth, scaleHeight);   
		// 得到新的圖片   www.2cto.com
		Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);   
		return newbm;   
	}  

}

這個代碼還可以優化,可自定義屬性傳入屬性值,畫布寬高如果不用屏幕寬高,那麼ontouch的邊界檢測需要加判斷,這裏相關代碼就不提供了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章