お絵かきアプリですが、前回までで、おしまいと思っていたのですが、より簡単な方法があったので、もう一度作成をしてみたいと思います。
Android で再開する Java プログラミング(10) – 手書きメモを作る
で保存の部分を確認していたところ、bitmapに直接記述を行う部分が書いてあり、その方法です。
あと、今まで描画に際してonDrawでpaintを作成していたのですが、何度も呼び出すファンクションなのでコンストラクタで作った方が良い気がするので、今回はその方法も入れてみました。
public penView(Context context) { super(context); //初期設定で作成してしまう。 paint = new Paint(); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(6); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeJoin(Paint.Join.ROUND); }
次にBitmapを作成してみます。
protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w,h,oldw,oldh); bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); bmpCanvas = new Canvas(bmp); }
Bitmapを生成する際に第三引数にBitmap.Config.ARGB_8888と入れますが、これは32ビットのARGBデータでBitmapを作成する事を、示しています。通常androidで使用しているColorの値がこれに該当しますので、特に指定の必要がなければこの値をいれてください。
参照:グラフィックス(6)-Bitmapの描画とMatrixの操作
onSizeChangedは表示されるタイミングで呼び出され、viewの表示領域の値を取得できるので、この関数で、viewを設定します。
また、タッチのイベントでは、このCanvasに線を書きます。
public boolean onTouchEvent(MotionEvent e){ switch(e.getAction()){ case MotionEvent.ACTION_DOWN: //最初のポイント oldx = e.getX(); oldy = e.getY(); break; case MotionEvent.ACTION_MOVE: //途中のポイント bmpCanvas.drawLine(oldx, oldy, e.getX(), e.getY(), paint); oldx = e.getX(); oldy = e.getY(); invalidate(); break; default: break; } return true; }
Canvasのdarwのファンクションは常に上書きになるので、bmp上に線が上書きされていきます。このbmdをonDrawでViewに書き写します。
public void onDraw(Canvas canvas) { canvas.drawBitmap(bmp, 0, 0, null); }
以上で簡単にですが、ビットマップを作成する事ができました。
ソースは以下です。
package in.andante.drawbm; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.MotionEvent; import android.view.View; public class penView extends View { private float oldx = 0f; private float oldy = 0f; private Bitmap bmp = null; private Canvas bmpCanvas; private Paint paint; public penView(Context context) { super(context); //初期設定で作成してしまう。 paint = new Paint(); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(6); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeJoin(Paint.Join.ROUND); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w,h,oldw,oldh); bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); bmpCanvas = new Canvas(bmp); } public void onDraw(Canvas canvas) { canvas.drawBitmap(bmp, 0, 0, null); } public boolean onTouchEvent(MotionEvent e){ switch(e.getAction()){ case MotionEvent.ACTION_DOWN: //最初のポイント oldx = e.getX(); oldy = e.getY(); break; case MotionEvent.ACTION_MOVE: //途中のポイント bmpCanvas.drawLine(oldx, oldy, e.getX(), e.getY(), paint); oldx = e.getX(); oldy = e.getY(); invalidate(); break; default: break; } return true; } }
線毎のデータを保持する必要がなければこの方法が一番シンプルな気がします。