サイト移転のお知らせ:http://techbooster.org/に移転しました

Canvasの状態を保存/復帰させる

5月 27, 2011   //   by @mhidaka   //   マルチメディア  //  No Comments

View#onDrawメソッドの表示処理ではCanvasを用いて描画を行います。複数のBitmapやオブジェクトを表示したい場合は描画ごとに表示位置を計算する必要があります。Canvasの状態を保存する主な目的は描画処理の簡略化です。描画位置がわかりやすくなるほか、任意のタイミングでCanvasの状態を復帰させられるメリットがあります。プログラミング上でのテクニックとしてどうぞ。

  • Canvas#save() 状態を保存する
  • Canvas#restore() 保存した状態へ復帰する

Canvas#save/restoreメソッドで保存できるのは回転、平行移動、図形のゆがみなどを表現するmatrix、表示範囲を指定するclip、の2種類の情報です。アプリケーションのスクリーンショットを取得するように1ピクセルの色情報単位で保存・復帰することはできませんので注意してください。

サンプルコード

以下のソースコードを実行すると画像のように直立したマスコット(緑)と傾いたマスコット(赤)が重なって描画されます。

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);

            canvas.drawBitmap(mAndroidGreen, 0, 0, mPaint);
            //現在の状態を覚える
            canvas.save();

            //一時的に移動
            canvas.rotate(45);
            canvas.drawBitmap(mAndroidRed, 0, 0, mPaint);

            //移動した分を元に戻す(-45)
            canvas.restore();
        }

6行目で状態を保存します。45度Canvasを回転させてマスコット(赤)を描画した後、13行目で状態を復帰させています。


図示することで、わかりやすく説明できます。図中の1~4の順番でソースコードを実行、描画しています。

  1. Canvas#saveメソッドで現在のCanvas状態(行列matrixと表示範囲clip)を保存
  2. Canvasを45度回転させる
  3. 回転後のCanvasに対してマスコット(赤)をdraw
  4. Canvas#restoreメソッドで元のmatrixと表示範囲に復帰

サンプルコードの全体の解説はつづきから。

CanvasActivity.java

public class CanvasActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new CustomView(this));
    }

    private static class CustomView extends View {

        private Paint mPaint;

        private Bitmap mAndroidGreen;
        private Bitmap mAndroidRed;

        public CustomView(Context context) {
            super(context);
            setFocusable(true);

            mPaint = new Paint();

            Resources res = getResources();
            mAndroidGreen = BitmapFactory.decodeResource(res, R.drawable.android_green);
            mAndroidRed = BitmapFactory.decodeResource(res, R.drawable.android_red);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);

            canvas.drawBitmap(mAndroidGreen, 0, 0, mPaint);
            //現在の状態を覚える
            canvas.save();

            //一時的に移動
            canvas.rotate(45);
            canvas.drawBitmap(mAndroidRed, 0, 0, mPaint);

            //移動した分を元に戻す(-45)
            canvas.restore();
        }
    }
}

CanvasActivityはCustomViewを内部クラスに持ち、CustomViewのコンストラクタでリソースを読み込みます。
View#onDrawメソッドでCanvas#save, Canvas#restoreメソッドを利用して画像描画を行っています。

関連する記事:

Sponsored Link

Comments are closed.

技術書新刊 発売中

アンドロイドアカデミアには、CIやテスト、互換検証など実務に生きるノウハウをあつめています

技術書新刊 発売中

Android Next!はAndroid 7.0に対応したはじめての技術書です!


The Web Explorer 2はCSSの中央寄せやWebAudioなど未来を読み解く一冊です


Revised TypeScript in DefinitelylandはTypeScript 2.0(β)に対応した解説書です。インストールから型定義まで幅広くサポートしています


技術書をかこう!はエンジニアらしい執筆環境を構築、HowTo本です