520 likes | 663 Views
画像とアニメーション. 6/1. 前回の内容. リスト スピナ メニュー ダイアログ. 本日の内容. エラーがでた時の対処法 画像の読み込みと表示 画像の回転 画像 の 拡大 図形の描画 アニメーション. エラーがでた時の対処法. これからソースコードが長くなったり、画像や音声ファイルを扱ったりするのでエラーが出る機会が増えるかもしれません そこでプログラムにエラーが出てる場合と実行時にエラーがでた場合のヒントになるログの出し方を説明します. プログラムにエラーがでた場合. あってるはずなのにエラーが出てる …… ?. 困った …….
E N D
画像とアニメーション 6/1
前回の内容 • リスト • スピナ • メニュー • ダイアログ
本日の内容 • エラーがでた時の対処法 • 画像の読み込みと表示 • 画像の回転 • 画像の拡大 • 図形の描画 • アニメーション
エラーがでた時の対処法 • これからソースコードが長くなったり、画像や音声ファイルを扱ったりするのでエラーが出る機会が増えるかもしれません • そこでプログラムにエラーが出てる場合と実行時にエラーがでた場合のヒントになるログの出し方を説明します
プログラムにエラーがでた場合 • あってるはずなのにエラーが出てる……? 困った……
プログラムにエラーがでた場合 • 行番号の✕印をクリックすると、解決策が表示されます ※解決策が表示されない場合もあります importが抜けてたのか
ログの出し方 • 実行時にエラーがでた場合は、アプリが強制終了してしまうため何が原因なのかわかりません • しかし、ログにエラーが出ていることがあります
ログの出し方 • ウィンドウ->ビューの表示->その他 とクリックします
ログの出し方 • AndroidにあるLogCatを選びOKを押します
ログの出し方 • Errorを選択すると、エミュレーター内で発生したエラーの一覧が出るので、そこから自分の作ったプログラムと関係がありそうな部分を探します
画像の読み込みと表示 • プロジェクト内に画像ファイルを置き、それをアプリ内で表示する方法を紹介します
画像フォルダの作成 プロジェクトのresフォルダーをクリックし 右クリック->新規->フォルダー で新しくフォルダーを作成します
画像フォルダの作成 drawableという名前にして、完了を押します
画像ファイルの追加 drawableフォルダができたら、そこにアプリで表示する画像ファイルを置きます ファイルを置けたら、ImageViewTest.javaをコピーして実行してみましょう ※デバイスの解像度によって画像を変える場合は、元々あるdrawable-hdplフォルダ等にそれぞれ置きます
リソースへの登録 • 画像ファイルを置くと、R.javaに自動的にIDが割り当てられます • アプリ内で画像を使う場合は、ここで割り当てられたIDを使用します ImageTestActivity.javaを実行してみましょう
実行結果 drawableフォルダに置いた画像が表示されました
ソースの中身 import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.widget.ImageView; import android.widget.LinearLayout; public class ImageTestActivity extends Activity { ImageViewiv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayoutll = new LinearLayout(this); ll.setOrientation(LinearLayout.HORIZONTAL); setContentView(ll); iv = new ImageView(this); Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.tulip_rd); iv.setImageBitmap(bmp); ll.addView(iv); } } ① ② ③
イメージビューの生成 • 画面に画像を表示するにはImageViewというビューを使います ImageView iv; iv = new ImageView(this);
画像データの取得 • ビットマップオブジェクトを作り、画像のIDから画像を読み込みます Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.tulip_rd); アプリケーションのリソースを管理しているもの 置いた画像に割り当てられたID
イメージビューへの設定 • 画像データを取得できたら、イメージビューに画像をセットします iv.setImageBitmap(bmp); 最後にレイアウトにイメージビューを追加すれば画像が表示できます
練習 • 適当な画像を用意して、表示してみましょう
画像の回転 • 読み込んだ画像は、座標を扱うMatrixオブジェクトのメソッドを呼び出すことで回転ができます RotateTestActivity.javaを実行してみましょう
ソースコード public class RotateTestActivity extends Activity { ImageView iv; Bitmap bmp; Matrix m; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayoutll = new LinearLayout(this); ll.setOrientation(LinearLayout.HORIZONTAL); setContentView(ll); iv = new ImageView(this); bmp = BitmapFactory.decodeResource(getResources(), R.drawable.tulip_rd); m = new Matrix(); m.postRotate(90); bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true); iv.setImageBitmap(bmp); ll.addView(iv); } } ① ② ③
マトリックスオブジェクトの生成 • 画像の回転をするために必要な行列を扱うマトリックスオブジェクトを生成します Matrix m; m = new Matrix();
回転する角度の設定 • postRotateメソッドを使って回転する角度を設定します m.postRotate(90); この例だと右に90度回転します
画像の回転 • createBitmapメソッドを使って、読み込んだ画像にマトリックスの設定をします bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),bmp.getHeight(), m, true); 元の画像ファイル 画像に設定するマトリックスオブジェクト ※上のメソッドの 0,0,bmp.getWidth(),bmp.getHeight()は元画像から抜き出す矩形を意味し、 0,0,bmp.getWidth()/2,bmp.getHeight() とすると元の画像の左半分だけを抜き出すことができる
練習 • 下の図のように画像を180度回転させて表示してみましょう ※画像を回転させる前にsetImageBitmapでイメージビューに画像を設定してしまうと回転しません
画像の拡大 • 画像の拡大も、回転と同様にMatrixオブジェクトのメソッドを呼び出すことで拡大できます ScaleTestActivity.javaを実行してみましょう
実行結果 • 元の画像の縦3倍、横3倍の大きさの画像が表示されました
ソースコード public class ScaleTestActivity extends Activity { ImageViewiv; Bitmap bmp; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayoutll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); setContentView(ll); bmp = BitmapFactory.decodeResource(getResources(), R.drawable.tulip_rd); iv = new ImageView(this); ll.addView(iv); Matrix m = new Matrix(); m.postScale(3,3); bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true); iv.setImageBitmap(bmp); } } ①
拡大率の設定 • postScaleメソッドを呼び出すことで拡大処理が出来ます m.postScale(3,3); ※縮小するには0<n<1の値を指定します ※仕様で引数がfloat(doubleよりもbit数が少ない実数)なので、実数で指定する時はfloatでキャストするか、fをつけます
練習 • 下の図のように画像を回転させつつ縮小して表示してみましょう ※画像を回転・縮小させる前にsetImageBitmapでイメージビューに画像を設定してしまうと回転しません
図形の描画 • これまではボタンを配置したり画像を表示したりしてきましたが、ビュー上に絵を描いて表示することも可能です
実行結果 • 白い円が表示されました
ソースコード public class DrawTestActivity extends Activity { SampleViewsv; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayoutll = new LinearLayout(this); setContentView(ll); sv = new SampleView(this); ll.addView(sv); } class SampleViewextends View { public SampleView(Context cn) { super(cn); } public void onDraw(Canvas cs) { super.onDraw(cs); Paint p = new Paint(); p.setColor(Color.WHITE); p.setStyle(Paint.Style.FILL); cs.drawCircle(50, 50, 10, p); } } } ① ② ③
ビュークラスの作成 • これまではテキストビューやリストビューなど用意されたビューを使ってきましたが、今回は自分でビューを継承したクラスを作ります SampleViewsv; public void onCreate(Bundle savedInstanceState) { sv = new SampleView(this); } class SampleViewextends View { }
コンストラクタの作成 • ビューを継承したクラス内では、まずコンストラクタを作成します public SampleView(Context cn) { super(cn); } ※コンストラクタとは、クラスからオブジェクトを作成した際に、自動的に実行されるメソッドのことをいい クラス名(){ .... } のように書かれます。()内に引数が入ることもあります
描画 • 絵の描画はonDrawメソッド内で実行します。Paintオブジェクトで色や塗り方などを指定しCanvasクラスに用意されているメソッドを使って描きます Paint p = new Paint(); p.setColor(Color.WHITE);//色を白にする p.setStyle(Paint.Style.FILL);//塗りつぶす cs.drawCircle(50, 50, 10, p);//(50,50)の位置に半径10の円を描く
塗りつぶし方 • 塗りつぶし方には輪郭のみ・内部のみ・輪郭と内部の3種類があります //輪郭線の太さ p.setStrokeWidth(5); p.setStyle(Paint.Style.FILL); cs.drawCircle(50, 50, 10, p); p.setStyle(Paint.Style.FILL_AND_STROKE); cs.drawCircle(50, 80, 10, p); p.setStyle(Paint.Style.STROKE); cs.drawCircle(50, 110, 10, p); } ※座標は左上が0,0です
描ける形1 • Canvasクラスには様々なメソッドがあります 円引数:x座標・y座標・半径 drawCircle(30, 30, 50, paint); 線引数:始点のx座標・始点のy座標・終点のx座標・終点のy座標 drawLine(0,0,100,150, paint); 文字列引数:文字列・先頭のx座標・先頭のy座標 drawText("テスト", 30, 70, paint);
描ける形2 背景引数:赤の強さ(0-255),緑の強さ(0-255),青の強さ(0-255) cs.drawRGB(0, 0, 100); 四角引数:1個目の頂点のx座標,y座標,反対にあるx座標,y座標 cs.drawRect(0, 0, 100,100, p); 点引数:x座標,y座標 cs.drawPoint(100,100, p); 画像引数:画像ファイル,x座標,y座標 cs.drawBitmap(bmp,100,100,p);
注意点 実行したメソッドから描画していくので順番に気をつける必要があります cs.drawPoint(100,100, p); cs.drawBitmap(bmp,100,100,p); cs.drawRGB(0, 0, 100); cs.drawRGB(0, 0, 100); cs.drawPoint(100, 100, p); cs.drawBitmap(bmp, 100, 100, p);
アニメーション • 少しずつオブジェクトの座標をずらしながら描画することでアニメーションを作成できます AnimationTestActivity.javaを実行してみましょう
実行結果 • 円が左右に行ったり来たりします
ソースコード1 SampleViewsv; Handler hn; float x, y, dx, dy; intwidth, height; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayoutll = new LinearLayout(this); setContentView(ll); hn = new Handler(); hn.postDelayed(this, 10); sv= new SampleView(this); ll.addView(sv); } public void run() { WindowManagerwm = (WindowManager) getSystemService(WINDOW_SERVICE); Display dp = wm.getDefaultDisplay(); width = dp.getWidth(); height = dp.getHeight(); if (x < 0 || x > dp.getWidth()){ dx = -dx; } x += dx; sv.invalidate(); hn.postDelayed(this, 10); } ① ③ ②
ソースコード2 class SampleView extends View { public SampleView(Context cn) { super(cn); x = 0; y = 50; dx = 10; } public void onDraw(Canvas cs) { super.onDraw(cs); Paint p = new Paint(); p.setColor(Color.WHITE); p.setStyle(Paint.Style.FILL); cs.drawCircle(x, y, 10, p); } }
ハンドラーの指定 • アニメーションでは、何回も描画するオブジェクトの移動と描画を繰り返す必要があります • そこで定期処理ハンドラという一定時間ごとに処理をするメソッドを呼び出せるHandlerクラスを使います Handler hn; hn = new Handler(); hn.postDelayed(this, 10);//10ミリ秒後にrunメソッドを実行します
runメソッド • runメソッドの中が繰り返し実行される部分です • 最後にpostDelayedメソッドを呼び出すことで10ミリ秒後に再度実行するようになっています public void run() { : sv.invalidate(); hn.postDelayed(this, 10); } ※Invalidateメソッドは最描画するメソッドです
跳ね返り処理 runメソッドでは円のx座標を10づつずらして描画していますが、画面から飛び出さないようにしています WindowManagerwm = (WindowManager) getSystemService(WINDOW_SERVICE);//システム情報の取得 Display dp = wm.getDefaultDisplay();//画面オブジェクト width = dp.getWidth(); //画面の横幅 height = dp.getHeight(); //画面の縦幅 if (x < 0 || x > width) //座標が左端か右端なら dx = -dx; //向きを反転させる x += dx; //座標更新