Androidプログラミング日記 (仮)  

画像回転方法

あなたは

人目のプログラマーだよ。

Androidプログラミング日記 (仮).

 

 

 

 

画像回転

今回は画像回転方法を勉強しました。画像の回転方法は色々あるみたいでしたがたどりついた表示方法がありました。それまでの勉強がすべて無になるような表示方法だったので、この表示方法を見つけたときはあっけにとられました。しかしながらたどり着くまでにの実際使用したプログラムコードをご紹介します。

何もない画面に画像を表示させて回転させても、ちゃんと意図した場所に表示されて、ちゃんと思った通りの回転をしているのかたしかめるためのコードです。といってもたいしたものでもないです。

簡単ですよ

みなさんも実験的なことをする時にこういう実験専用プログラムを作成するんではないでしょうか。とりあえずコードの紹介です。ファイルは3つとmainxmlのちょっとした変更です。

   
 

ファイル名「ViewTestActivity.java」

package and.roid.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {
private Context context;

private Mushi mushi;//Mushiクラス準備
private Bitmap img;//大元の画像取り入れ用準備
private Bitmap[] imgs;//Mushiクラス登録用画像準備

int w,h;
public MyView(Context context) {
super(context);
// TODO 自動生成されたコンストラクター・スタブ
}
public MyView(Context context,AttributeSet attrs){
super(context,attrs);
this.context = context;

imgs = new Bitmap[4];//Mushiクラスに登録する為の分割画像用4つ
Resources resources = context.getResources();//画像登録準備
img = BitmapFactory.decodeResource(resources, R.drawable.mushirobo);//画像取り込み
w = img.getWidth();//画像の全体の幅
h = img.getHeight();//画像の全体の高さ
for(int i=0;i < imgs.length;i++){//画像を4分割して1つずつ配列に収納
imgs[i] = Bitmap.createBitmap(img, i*(w/imgs.length), 0, w/imgs.length, 150);
}
mushi = new Mushi(imgs);//取り込み元も配列にすれば一気に登録できます
}

protected void onDraw(Canvas c){
super.onDraw(c);
Paint p = new Paint();
c.drawColor(Color.BLACK);
p.setColor(Color.RED);
c.drawLine(0, c.getHeight()/2, c.getWidth(), c.getHeight()/2, p);
c.drawLine(c.getWidth()/2, 0, c.getWidth()/2, c.getHeight(), p);

mushi.draw(c,c.getWidth(),c.getHeight());//画像表示
}

}

 
 

ファイル名「MyView.java」

package and.roid.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {
private Context context;

private Mushi mushi;//Mushiクラス準備
private Bitmap img;//大元の画像取り入れ用準備
private Bitmap[] imgs;//Mushiクラス登録用画像準備
public MyView(Context context) {
super(context);
// TODO 自動生成されたコンストラクター・スタブ
}
public MyView(Context context,AttributeSet attrs){
super(context,attrs);
this.context = context;

imgs = new Bitmap[4];//Mushiクラスに登録する為の分割画像用4つ
Resources resources = context.getResources();//画像登録準備
img = BitmapFactory.decodeResource(resources, R.drawable.mushirobo);//画像取り込み
int w = img.getWidth();//画像の全体の幅
int h = img.getHeight();//画像の全体の高さ
for(int i=0;i < imgs.length;i++){//画像を4分割して1つずつ配列に収納
imgs[i] = Bitmap.createBitmap(img, i*(w/imgs.length), 0, w/imgs.length, 150);
}
mushi = new Mushi(imgs);//取り込み元も配列にすれば一気に登録できます
}

protected void onDraw(Canvas c){
super.onDraw(c);
Paint p = new Paint();
c.drawColor(Color.WHITE);

mushi.draw(c);//画像表示
}

}

 
 

ファイル名「Mushi.java」

package and.roid.view;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

public class Mushi {

private Drawable[] img;
private int x,y;
private int wh;
private int cwh;
Mushi(Bitmap[] imgs){
this.img = new Drawable[4];
for(int i=0;i<this.img.length;i++){
this.img[i] = new BitmapDrawable(imgs[i]);
}
x=0;
y=0;
wh=50;
cwh = 25;
}
public void draw(Canvas c,int cw, int ch){

img[0].setBounds(x, y, x+wh/2,y+wh/2);

img[0].draw(c);
}

}


 
     
 

 

 
 

配列を使用する表示と配列を使用しないやり方だと、ちょっと違うので実験で積極的に使用して慣れていくようにしています。画面を黒くして画面中心に赤線の交点がくるようにしています。

今回はまだ座標(0,0)ですのでちゃんと左上に画像が表示されています。画像を小さくしているのにはワケがあります。後述でわかります。

「Drawable」での表示を今回はしています。「Bitmap」で画像を取り込みクラスに渡す時に「Drawable」で受け取っています。this.img[i] = new BitmapDrawable(imgs[i]);

img[0].setBounds(x, y, x+wh/2,y+wh/2);

img[0].draw(c);

「setBounds」でその画像の左上座標右上座標を設定して座標と大きさを決めます。そしておもむろに「Draw」ですね。これで表示されます。簡単ですね。次はいよいよ回転です。

とりあえず画像を中心に置いてみたいと思います。

 
   
     
 

ずれました。なにも補正をしてないのでここで補正をします。

public void draw(Canvas c,int cw, int ch){の下に
x=cw/2;y=ch/2;を付け加えます。画面全体の大きさをでint cw, int ch受け取ってます。なのでここからは画像のXY座標を画像の中心にあると考えて表示するようにします。なのでうけとった画面座標を2で割れば中心なので、画像の設置を中心に設定しました。

そこで今回は画像の大きさを50に設定しましたのでwhに代入。その半分の25をcwhに代入。

xy座標は中心なわけですからそこから画像のマイナス半分ずつはみでたところが画像の左上座標。プラス半分はみ出たところが右下座標ということで、

 
 
package and.roid.view;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

public class Mushi {
private Matrix matrix;
private Drawable[] img;
private int x,y;
private int wh;
private int cwh;

Mushi(Bitmap[] imgs){
this.img = new Drawable[4];
for(int i=0;i<this.img.length;i++){
this.img[i] = new BitmapDrawable(imgs[i]);
}
x=0;
y=0;
wh=50;
cwh = 25;
}
public void draw(Canvas c,int cw, int ch){
x=cw/2;y=ch/2;

img[0].setBounds(x-cwh, y-cwh, x+cwh,y+cwh);


img[0].draw(c);
}

}
 
   
     
 

これで中心に表示されました。さぁ、いよいよ回転です。回転方法には「Matrix」などもあるのですが今回はCanvasクラスを使用したやり方でやります。一番簡単だったので。

canvas.rotate(5); このように書きます。

角度は5度だけかたむけるようにしてみました。

 
 
package and.roid.view;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

public class Mushi {
private Matrix matrix;
private Drawable[] img;
private int x,y;
private int wh;
private int cwh;

Mushi(Bitmap[] imgs){
this.img = new Drawable[4];
for(int i=0;i
 
   
     
 

むぅ、意図しない表示がされました。中心からずれていますね。これで角度を45とかにしようものなら画面からはみ出てしまうのです。

「Canvas」を使用していることから、Canvasを回転していることがわかるでしょう。Canvasとは画面です。画面の左上座標を中心に回転しているわけです。しかしeclipseのいいところはこういう時に発揮します。

コードを呼び出すときに「.」を打ち込んだ時に、ズラッっとコードがでますよね。同じコードがかぶっている時もあります。その場合は引数が違うコードです。引数とはそのコードを使用する際に渡す値です。

画像などを扱う場合の引数は、ほとんどが座標などです。みてみるとありました。

c.rotate(degrees, px, py) こんなのがありました。degreesは角度ですね360のやつです。px,pyはこれはじつは中心座標を示します。迷わず書けよ、書けばわかるさ。

 
 
package and.roid.view;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

public class Mushi {
private Drawable[] img;
private int x,y;
private int wh;
private int cwh;

Mushi(Bitmap[] imgs){
this.img = new Drawable[4];
for(int i=0;i<this.img.length;i++){
this.img[i] = new BitmapDrawable(imgs[i]);
}
x=0;
y=0;
wh=50;
cwh = 25;
}
public void draw(Canvas c,int cw, int ch,Paint p){
x=cw/2;y=ch/2;

img[0].setBounds(x-cwh, y-cwh, x+cwh,y+cwh);
c.rotate(45, x, y);
img[0].draw(c);
}

}
 
   
     
 

大成功です。見事中心で回転してますね。

しかし色々疑問もあるのです。このコードにいきつくのに色々なやり方をやってきたのですが、canvasごと回転したと同時に、他の画像やテキストも一緒に回転してしまい、回転させたい画像の前後にsave()、 restore()で回転させたくない画像を保護したり・・・と悪戦苦闘していたのですが、なにげなくこのコードだけでやってみると回転させたい画像だけが回転してしまった。という感じです。この先そういうコードも必要になってくるのでしょうが、とりあえず回転したし、今は満足です。

 

画像回転ができるようになったので色々できるようになりました。でもアプリ開発での一番の問題っていうのは、

「どんなアプリを作ろうか」

というアイデアなんですよね。とりあえずマネでもいいので作っていくしかないのですがなんか作りたくなるようなアイデアがないかなぁと思う今日このごろです。

 

Androidプログラミング日記 (仮) | サイトマップ | 個人情報保護方針 | 応援メールテヘペロ | ©2012 Japan  相互リンク大募集中です