ビットマップ画像を中心を軸に拡大・縮小する
今回は、オリジナルの View(MyScale.class)に配置したビットマップ画像をマトリックス(Matrix)を使って画像の中心を軸に拡大・縮小します。View に配置したビットマップ画像の中心を軸に拡大・縮小する方法がわからないという方は、ぜひ参考にしてください。
サンプルコード①(MainActivity.java)
MainActivity.java では、別ファイルで用意したオリジナルの View(MyScale.class)を読み込んでいます。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//オリジナルの View(MyScale.class)をセットして使用
setContentView(new MyScale(this));
}
サンプルコード②(MyScale.java)
MyScale.java は実際に画面の表示と制御を行っているファイルです。サンプルコードの詳しい説明はコード内のコメントを参照してください。
public class MyScale extends View {
//オブジェクト・変数の準備
private Bitmap bitmap1; //ビットマップ画像
private Resources resources1; //リソース
private BitmapFactory.Options options1; //ビットマップオプション
private Timer timer1; //タイマー
private float scale_x, scale_y; //ビットマップ画像の表示倍率
private boolean kakudai; //拡大・縮小判定用
public MyScale(Context context) {
super(context);
//プロジェクトのリソースにアクセスするための準備
resources1 = context.getResources();
//ビットマップを読み込む際のオプションを準備
options1 = new BitmapFactory.Options();
//スケーリングを無効にセット(原寸大表示にする)
options1.inScaled = false;
//リソース(drawable)から画像を読み込んで、同時にオプションを適用
bitmap1 = BitmapFactory.decodeResource(resources1, R.drawable.donbei, options1);
//Viewの背景色を赤色にする
setBackgroundColor(Color.RED);
//拡大・縮小を判断する変数の初期化(trueで拡大)
kakudai = true;
//ビットマップ画像の表示倍率を初期化
scale_x = 0f;
scale_y = 0f;
//タイマーをインスタンス化
timer1 = new Timer();
//タイマーにスケジュールを設定してタイマーをスタート
timer1.schedule(new TimerTask() {
@Override
public void run() {
//ビットマップ画像の表示倍率の計算
if (kakudai == true) {
//拡大率を上げる
scale_x += 0.01f;
scale_y += 0.01f;
} else if (kakudai == false) {
//拡大率を下げる
scale_x -= 0.01f;
scale_y -= 0.01f;
}
//描画の更新(描画メソッドが実行される)
postInvalidate();
//ビットマップ画像の横幅で拡大・縮小を判断
if (scale_x > 4f) {
//縮小モードにする
kakudai = false;
} else if(scale_x < 0f) {
//拡大モードにする
kakudai = true;
}
}
},10,10); //10ms後に10ms間隔で実行
}
//描画メソッド
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvasに文字を表示するためのPaintの準備
Paint paint = new Paint(); //ペイントの生成とインスタンス化
paint.setAntiAlias(true); //アンチエイリアスを有効
paint.setColor(Color.WHITE); //文字を白色に設定
paint.setTextSize(40); //文字サイズを50に
//マトリクスを生成してインスタンス化
Matrix matrix1 = new Matrix();
//マトリクスに幅と高さの表示倍率とピボット(中心となる)位置を設定
matrix1.setScale( scale_x, scale_y, bitmap1.getWidth() / 2, bitmap1.getHeight() / 2);
//マトリクスに移動座標を設定
matrix1.postTranslate( 600f, 800f);
//canvasにビットマップ画像を表示
canvas.drawBitmap( bitmap1, matrix1, null);
//テキスト文字の表示
canvas.drawText("現在の表示倍率:横幅 " + scale_x + " 倍",10,50, paint);
canvas.drawText("現在の表示倍率:高さ " + scale_y + " 倍",10,100, paint);
}
}
サンプルコード③(AndroidManifest.xml)
マニフェストファイルの変更はありません。
サンプルコード④(activity_main.xml)
画面表示にはオリジナルの View(MyScale.class)をセットしているので、レイアウトファイルは使用しません。
実行結果
① 起動すると X座標600px、Y座標800px の位置にビットマップ画像が表示され、画像の中心を軸に 10ms 間隔で徐々に拡大します。
② ビットマップ画像の横幅の拡大率が4倍以上になると拡大がストップして、今度は徐々に縮小していきます。
③ アプリを終了するまで拡大と縮小を繰り返します。
備考・その他
実行画面に表示されている幅と高さの拡大率をみるとわかる通り float(浮動小数点)には微妙な誤差が生まれてしまうので「float変数 == 整数値」という判断はできません。扱いにはくれぐれも注意が必要です。
END