2012年02月10日

手書き入力を行う(1)


手書き入力を行うために・・・
onTouchEventを取得する
今回は応用編
前回説明のPathを利用して手書き入力を行いたいと思います
Pathによる線の描画
まずはViewクラスの独自クラスを作成するところまでは同じです
Viewクラスへのグラフィックの描画
その中には描写を担当するViewメソッドがありますが
今回はその中にonTouchEventを追加します
		 //イベントのタイプごとに処理を設定  
		 public boolean onTouchEvent(MotionEvent e){  
			switch(e.getAction()){
			case MotionEvent.ACTION_DOWN: //最初のポイント  
			//押された時のイベント記入
			break;  
			case MotionEvent.ACTION_MOVE: //途中のポイント  
			//そのまま移動時のイベント記入
			break;  
			case MotionEvent.ACTION_UP: //最後のポイント  
			//離された時ののイベント記入
			break;  
			default://その他
				break;  
			}  
			return true;  
		}  
onTouchEventは画面がタッチされた時、そのまま移動したとき、離した時のイベントをそれぞれ取得します
MotionEvent.ACTION_DOWN:・・・タッチされた時
MotionEvent.ACTION_MOVE:・・・移動したとき
MotionEvent.ACTION_UP:・・・離したとき

押された場所を取得する
押された場所はe.getX();およびe.getY();でそれぞれx座標・y座標を取得します
まずはfloatで変数を定義します
    	 private float pos_x = 0f; //イベントが起きたX座標  
    	 private float pos_y = 0f; //イベントが起きたY座標  
タッチされた時に座標を取得し
moveToで移動します
				pos_x = e.getX();//x座標取得
				pos_y = e.getY();//y座標取得
				//押されたPointに移動
				path.moveTo(e.getX(), e.getY());
移動中は同様に取得し今度は
lineToで線を描きます
				pos_x = e.getX();  
				pos_y = e.getY();  
				path.lineTo(pos_x, pos_y);  
				invalidate();
path.lineToでpathに入れた後にinvalidate();
でonDrawで描写します

Viewの状態を保存するためのBitmapを作成
最後に指が離れたときにbitmapとして保存させます
まずはbitmapを新規で作成します
 //Viewの状態を保存するためのBitmap
private Bitmap bitmap = null;
次に
setDrawingCacheEnabled(); を使用しキャッシュ機能をオンにして画面状態を保持します
保持した画面をbitmapに保存し再びキャッシュ機能をオフにすることで保存が可能です
				path.lineTo(e.getX(), e.getY());  
				//キャッシュの中からキャプチャを作成するので、その一瞬の為にキャッシュをON  
				setDrawingCacheEnabled(true);  
				bitmap = Bitmap.createBitmap(getDrawingCache());  
				setDrawingCacheEnabled(false);

まとめ
1.タッチされたポイントにmoveTo
2.移動中はlineToで描き続ける
3.離されたときにbitmap保存
4.onDrawで描写の設定
となります
以下に全体を載せますんで参考に・・・
package draw.test;
 
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
 
public class DrawActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //カスタムビューを表示
        setContentView(new CustomView(this));
        }
    }

     
    //独自クラス
    class CustomView extends View {
    	 private float pos_x = 0f; //イベントが起きたX座標  
    	 private float pos_y = 0f; //イベントが起きたY座標  
    	 
    	 private Path path = null; //パス新規作成  
    	 private Bitmap bitmap = null; //Viewの状態を保存するためのBitmap  
		 public CustomView(Context context) {
		     super(context);
		     setFocusable(true);
		 }
		
		 //イベントのタイプごとに処理を設定  
		 public boolean onTouchEvent(MotionEvent e){  
			switch(e.getAction()){
			case MotionEvent.ACTION_DOWN: //最初のポイント  
				path = new Path();//pathを新規作成
				pos_x = e.getX();//x座標取得
				pos_y = e.getY();//y座標取得
				//押されたPointに移動
				path.moveTo(e.getX(), e.getY());
			break;  
			case MotionEvent.ACTION_MOVE: //途中のポイント  
				pos_x = e.getX();  
				pos_y = e.getY();  
				path.lineTo(pos_x, pos_y);  
				invalidate();  
			break;  
			case MotionEvent.ACTION_UP: //最後のポイント  
				path.lineTo(e.getX(), e.getY());  
				//キャッシュの中からキャプチャを作成するので、その一瞬の為にキャッシュをON  
				setDrawingCacheEnabled(true);  
				bitmap = Bitmap.createBitmap(getDrawingCache());  
				setDrawingCacheEnabled(false);  
				invalidate();  
			break;  
			default://その他
				break;  
			}  
			return true;  
		}  
		
		 protected void onDraw(Canvas canvas) {
		     super.onDraw(canvas);
		     if(bitmap != null){  
		    	 canvas.drawBitmap(bitmap, 0, 0, null);  
		    	 }  
			//この間にグラフィック描画のコードを記述する
			Paint paint = new Paint();
			//色を設定
			paint.setColor(Color.YELLOW);
			//線の太さを指定
			paint.setStrokeWidth(5);
			//線を滑らかに書く
			paint.setAntiAlias(true);
			//線で描く
			paint.setStyle(Paint.Style.STROKE);
			//端点を丸く
			paint.setStrokeCap(Paint.Cap.ROUND);
			//つなぎ目を丸く
			paint.setStrokeJoin(Paint.Join.ROUND);
			//pathを描写
			 if(path != null){  
				 canvas.drawPath(path, paint);  
				 }  
		     //終了
        }
    }
draw13.png
スポンサードリンク

2012年02月09日

滑らかな曲線を描写する


曲線を描写するには前回のPathにcubicToを使用します
cubicToでは3次ベジェ曲線というのを使用して曲線を描いています
wiki ベジェ曲線
詳細は省きますが(というかうまく説明できないw)
要するに始点と中点×2と終点を指定して曲線を描いているようです
path.moveToで始点に移動します
その次に
cubicTo(2点目のx座標 , 2点目のy座標 , 3点目のx座標 , 3点目のx座標 ,
終点のx座標 , 終点のy座標)で指定します
		 protected void onDraw(Canvas canvas) {
		     super.onDraw(canvas);
		
			//この間にグラフィック描画のコードを記述する
			Paint paint = new Paint();
			//色を設定
			paint.setColor(Color.YELLOW);
			//線の太さを指定
			paint.setStrokeWidth(5);
			//線を滑らかに書く
			paint.setAntiAlias(true);
			// 線で描く
			paint.setStyle(Paint.Style.STROKE);
			//pathを新規作成
			Path path = new Path();
			//始点座標
			path.moveTo(10,100);
			//中点×2+終点
			path.cubicTo(60, 50, 150, 50, 200, 200);
						
			path.moveTo(10,300);
			path.cubicTo(60, 200, 150, 400, 200, 300);
			canvas.drawPath(path, paint);
		     //終了
        }
draw12.png
単に曲線だけでなく、波打った形も描写できます
スポンサードリンク

Pathによる線の描画


Pathによる線の描画はペンで書くように
座標を指定していってまとめて描く事ができます
		 protected void onDraw(Canvas canvas) {
		     super.onDraw(canvas);
		
			//この間にグラフィック描画のコードを記述する
			Paint paint = new Paint();
			//色を設定
			paint.setColor(Color.MAGENTA);
			//線の太さを指定
			paint.setStrokeWidth(5);

			// 線で描く
			paint.setStyle(Paint.Style.STROKE);
			//pathを新規作成
			Path path = new Path();
			//RectFでの矩形を描写
			path.addRect(new RectF(10, 40, 110, 140), Direction.CW);
			path.moveTo(10, 40);//座標(10, 40)に移動
			path.lineTo(40, 10);//座標(40, 10)まで線を描く
			path.lineTo(140, 10);//以下同様
			path.lineTo(140, 110);
			path.lineTo(110, 140);
			path.moveTo(110, 40);
			path.lineTo(140, 10);
			//drawPathで描写
			canvas.drawPath(path, paint);
		     //終了
        }
draw11.png
まずRectFでまず矩形を描き、その次にPathを使って線を足しています
addRectのDirection.CWは時計回りに描写、CCWにすると反時計回りだそうです

スポンサードリンク

円弧の描画


円弧を描画するにはdrawArcを使用します
まずRectFで矩形領域を指定します
指定した領域内に円または楕円が書かれます
その中で表示される範囲をdrawArcで範囲を指定します

内容は
drawArc(RectF , float startAngle, float sweepAngle, boolean useCenter, paint)
となっています
RectFで指定した矩形領域に、角度startAngleを起点に時計回りに
角度sweepAngleの円弧を描きます
たとえばstartAngleが0で時計針の短針が3時の位置
180で9時の位置が開始位置になります
負の値を指定すると、反時計回りの角度にもできます
useCenterをtrueにすると、円の中心を含めて描画します
		 protected void onDraw(Canvas canvas) {
		     super.onDraw(canvas);
		
			//この間にグラフィック描画のコードを記述する
			Paint paint = new Paint();
			//色を設定
			paint.setColor(Color.MAGENTA);
			//線の太さを指定
			paint.setStrokeWidth(5);
			//アンチエイリアス(線を滑らかに)
			paint.setAntiAlias(true);
			// 線で描く
			paint.setStyle(Paint.Style.STROKE);
			//座標指定
			RectF rect = new RectF(50, 50, 200, 200);
			//円の中心を含めて描画
			canvas.drawArc(rect, 180,90,true,paint);
			//座標指定
			rect = new RectF(300, 50, 400, 200);
			//円弧のみ描写
			canvas.drawArc(rect, 180,-90,false,paint);
		     //終了
        }
draw10.png
スポンサードリンク

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。