Androidアプリ入門 No.76 2Dグラフィックスの基本 Canvasの基本
2Dグラフィックスの基本
Canvasの基本
最初に基本的な図形の描画を確認する。以下の条件でプロジェクトを作成する。
項目 | 内容 |
---|---|
Project name | Android2D |
Build Target | Android 1.6 |
Application name | Android2D |
Package name | sample.a2 |
Create Activity | Android2DActivity |
Min SDK Version | 4 |
まずは、Activityではなくグラフィック描画用のViewを用意する。
package sample.a2; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.view.View; public class GraphicView extends View { public GraphicView(Context context) { super(context); } @Override public void onDraw(Canvas canvas) { // 座標系がわかるような罫線を引く Paint paint = new Paint(); paint.setColor(Color.argb(75, 255, 255, 255)); paint.setStrokeWidth(1); for (int y = 0; y < 800; y = y + 10) { canvas.drawLine(0, y, 479, y, paint); } for (int x = 0; x < 480; x = x + 10) { canvas.drawLine(x, 0, x, 799, paint); } // 線を書く paint.setColor(Color.RED); // だんだん大きくしていく。 for (int i = 1; i <= 10; i++) { paint.setStrokeWidth(i); canvas.drawLine(i * 20 - 10, 10, i * 20 + 10, 10, paint); } paint.setColor(Color.rgb(0, 255, 0)); paint.setStrokeWidth(10); canvas.drawLine(10, 40, 300, 70, paint); paint.setStrokeWidth(10); paint.setAntiAlias(true); canvas.drawLine(10, 60, 300, 90, paint); // 円を書く paint.setAntiAlias(false); paint.setColor(Color.BLUE); canvas.drawCircle(90, 150, 40, paint); paint.setColor(Color.RED); canvas.drawCircle(90, 150, 20, paint); // 中心店の確認用の線 paint.setColor(Color.GREEN); paint.setStrokeWidth(1); // Y座標は150が中心 canvas.drawLine(40, 150, 140, 150, paint); // X座標は90が中心 canvas.drawLine(90, 100, 90, 200, paint); // 矩形を書く paint.setColor(Color.RED); paint.setStrokeWidth(1); canvas.drawRect(10, 200, 50, 240, paint); paint.setColor(Color.BLUE); paint.setStrokeWidth(5); canvas.drawRect(10, 250, 50, 290, paint); // 多角形を書く paint.setColor(Color.RED); Path path = new Path(); path.moveTo(100, 300); path.lineTo(10, 350); path.lineTo(80, 330); canvas.drawPath(path, paint); // 文字を書く paint.setAntiAlias(false); paint.setColor(Color.rgb(255, 255, 0)); paint.setTextSize(36); canvas.drawText("あいうえお", 10, 400, paint); paint.setAntiAlias(true); canvas.drawText("あいうえお", 10, 450, paint); // Pathに沿って文字を書く paint.setColor(Color.RED); path = new Path(); path.moveTo(50, 500); path.lineTo(250, 500); path.lineTo(250, 600); path.lineTo(50, 600); canvas.drawTextOnPath("あいうえおかきくけこさしすせそ", path, 0, 0, paint); paint.setColor(Color.GREEN); } }
次に、そのViewを表示するAndroid2DActivity.javaを以下のようにする。
package sample.a2; import android.app.Activity; import android.os.Bundle; public class Android2DActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new GraphicView(this)); } }
使用したAPIを簡単に確認する。まずPaintクラスから解説する。Paintクラスは描画のための色やスタイルの情報のクラスとなる。Paintクラス自体は色やスタイルの情報を持つだけで実際の描画は行わない。色情報を設定するPaint#setColorメソッドの定義は以下のようになっている。
public void setColor(int color)
引数の詳細は以下。
引数 | 説明 |
---|---|
color | 色情報をint型で指定する。通常はintの数値をリテラルで指定するのは可読性に欠けるため、Colorクラスを用いたりリソースを用いて指定する。 |
Colorクラスでの色の指定は以下のパターンで行う。
引数 | 説明 |
---|---|
Color#rgb(int red, int green, int blue) | red、green、blueを0〜255の比率で指定する。 |
Color#argb(int alpha, int red, int green, int blue) | alpha、red、green、blueを0〜255の比率で指定する。 |
Color#定数 | 定数には、BLACK、BLUE、CYAN、DKGRAY、GRAY、GREEN、LTGRAY、MAGENTA、RED、TRANSPARENT、WHITE、YELLOW等がある。 |
線の幅は、Paint#setStrokeWidthメソッドで定義する。具体的な定義は以下。
public void setStrokeWidth(float width)
引数 | 説明 |
---|---|
width | 線の幅。 |
アンチエイリアスもAPIのレベルで行うことができ、Paint#setAntiAliasで設定できる。具体的な定義は以下。
public void setAntiAlias(boolean aa)
引数 | 説明 |
---|---|
aa | アンチエイリアスをする場合にはtrue。 |
アンチエイリアスの効果を拡大して確認。
次にPaintを用いて実際に描画を行う。描画はCanvasクラスを用いて行う。代表的なメソッドをいくつか解説する。まず、単純な線を引くCanvas#drawLineメソッドを説明する。定義は以下。
public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
引数 | 説明 |
---|---|
startX | 線を引くx座標の開始。 |
startY | 線を引くy座標の開始。 |
stopX | 線を引くx座標の終了。 |
stopY | 線を引くy座標の終了。 |
paint | 線を引くPaintクラスのインスタンス。 |
次に円を描画するCanvas#drawCircleメソッドを説明する。定義は以下。
public void drawCircle (float cx, float cy, float radius, Paint paint)
引数 | 説明 |
---|---|
cx | 円の中心のx座標。 |
cy | 円の中心のy座標。 |
radius | 円の半径。 |
paint | 円を描くPaintクラスのインスタンス。 |
次に矩形を描画するCanvas#drawRectメソッドを説明する。定義は以下。
public void drawRect (float left, float top, float right, float bottom, Paint paint)
引数 | 説明 |
---|---|
left | 矩形の左端のx座標。 |
top | 矩形の上端のy座標。 |
right | 矩形の右端のx座標。 |
bottom | 矩形の下端のy座標。 |
paint | 円を描くPaintクラスのインスタンス。 |
次に多角形の描画をするCanvas#drawPathメソッドを説明する。定義は以下。
public void drawPath(Path path, Paint paint)
引数 | 説明 |
---|---|
path | どのようなPathを描くか。 |
paint | Pathを描くPaintクラスのインスタンス。 |
ここで出てきたPathクラスは、任意の点を指定してそれらを結んだ形を塗りつぶして描画する。例のプログラムの以下の部分に当たる。
// 多角形を書く
paint.setColor(Color.RED); Path path = new Path(); path.moveTo(100, 300); path.lineTo(10, 350); path.lineTo(80, 330); canvas.drawPath(path, paint);
Pathクラスは、インスタンスを作成後、始点をPath#moveToメソッドで決める。その点から、任意の点をPath#lineToメソッドで結ぶ。drawPathの場合には点は閉じていなくても(最初の点に戻らなくても)自動的に閉じた形で矩形が描画される。
次に、Pathに沿って文字列を描画するPath#メソッドを説明する。定義は以下。
public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
引数 | 説明 |
---|---|
text | 描画する文字列。 |
path | どのようなPathを描くか。 |
hOffset | 横方向のオフセット。 |
vOffset | 縦方向のオフセット。 |
paint | Pathを描くPaintクラスのインスタンス。 |
図形の描画と違いpathは始点で閉じられることはない。Path#moveToからPath#lineToまでで描いたPathに沿って文字列が描画される。Pathよりも文字列のほうが長ければ文字列はそこで打ち切られる。
hOffsetとvOffsetの動きを確認するため以下のサンプルを実行する。GraphicViewのみ以下のように変更して実行する。GraphicView.javaは以下。
package sample.a2; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.view.View; public class GraphicView extends View { public GraphicView(Context context) { super(context); } @Override public void onDraw(Canvas canvas) { // 座標系がわかるような罫線を引く Paint paint = new Paint(); paint.setColor(Color.argb(75, 255, 255, 255)); paint.setStrokeWidth(1); for (int y = 0; y < 800; y = y + 10) { canvas.drawLine(0, y, 479, y, paint); } for (int x = 0; x < 480; x = x + 10) { canvas.drawLine(x, 0, x, 799, paint); } // Pathに沿って文字を書く paint.setColor(Color.RED); paint.setTextSize(36); Path path = new Path(); path.moveTo(100, 100); path.lineTo(400, 100); canvas.drawTextOnPath("あいうえお", path, 0, 0, paint); path = new Path(); path.moveTo(100, 200); path.lineTo(400, 200); canvas.drawTextOnPath("あいうえお", path, 50, 0, paint); path = new Path(); path.moveTo(100, 300); path.lineTo(400, 300); canvas.drawTextOnPath("あいうえお", path, 0, 50, paint); paint.setColor(Color.YELLOW); canvas.drawLine(100, 100, 400, 100, paint); canvas.drawLine(100, 200, 400, 200, paint); canvas.drawLine(100, 300, 400, 300, paint); } }
実行結果は以下のようになる。黄色い線でPathを表している。PathとのずれでhOffset、vOffsetの効果がわかるようになっている。