グラフィックス(6)-Bitmapの描画とMatrixの操作


drawBitmapメソッドの簡単なサンプル

CanvasクラスのdrawBitmapメソッドを使って、Bitmapを描画する事ができます。

以下に、drawBitmapメソッドを使ってBitmapを描画する、簡単なサンプルを示します。

1Resources r = getResources();
2Bitmap bmp = BitmapFactory.decodeResource(r, R.drawable.sample);
3 
4canvas.drawBitmap(bmp, 0, 0, null);

このプログラムを実行するには、res/drawableデレクトリに、画像ファイルsample.JPGが保存されている必要があります。

画像ファイルは、JPGだけでなくBMP,PNG,GIFも表示可能なようです。

BitmapFactory.decodeResourceメソッドは、res/drawableデレクトリの画像ファイルを、Bitmapオブジェクトとして取得するメソッドです。

drawBitmapメソッドは、CanvasにBitmapオブジェクトを描画するメソッドで、引数の意味については、次の「drawBitmapメソッドのオーバロードメソッド」を参照して下さい。

このプログラムを実行すると、以下のように、画像ファイルsample.JPGが表示されます。

 

 

drawBitmapメソッドのオーバロードメソッド

drawBitmapメソッドには、以下のようにオーバロードされたメソッドが存在します。

  • void drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
    Bitmapをcanvasの座標(left, top)の位置を起点として、描画します。
  • void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
    Bitmap内の矩形srcで囲まれた領域を、canvasの矩形dst領域に、描画します。
    結果としてBitmapの1部の領域を縮小・拡大して、canvasの矩形dst領域に、描画する事になります。
  • void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
    1つ前のメソッドのdst引数のクラスが、RectクラスではなくRectFクラスに、変わったものです。
  • void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
    matrixオブジェクトの操作に従って、Bitmapを描画します。
  • void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, Paint paint)
    引数colorsで示されるピクセル配列より、Bitmapを描画します。
  • void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, int height, boolean hasAlpha, Paint paint)
    1つ前のメソッドのレガシー(従来)バージョンで、引数x,yの型がfloatではなくint型になっています。
  • void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)
    BitmapMesh.java - Android Developersにサンプルプログラムがありますが、詳細はよくわかりませんでした。

矩形領域Rectを指定してBitmapの1部の領域を縮小・拡大してcanvasに描画する

次のプログラムは、Bitmap画像の右半分の画像を、縦横それぞれ半分の大きさに縮小して、座標(50, 50)の点を起点として、描画するサンプルです、

1int width = bitmap.getWidth();
2int height = bitmap.getHeight();
3 
4canvas.drawBitmap(bitmap, new Rect(width / 2, 0, width, height),
5        new Rect(50, 50, width / 4 + 50, height / 2 + 50), null);

このプログラムを実行すると、以下のように画像が表示されます。

 

 

Bitmapオブジェクトの新規作成とコピーとBitmapオブジェクト内のcanvasへの描画

Bitmapオブジェクトを新規に作成するには、BitmapクラスのcreateBitmapメソッドを使います。

既存のBitmapオブジェクトをコピーして、新たなBitmapオブジェクトを作成するには、Bitmapクラスのcopyメソッドを使います。

新規に作成したBitmapオブジェクトのCanvasオブジェクトを取得して、図形を描画する事もできます。

以下に、その例を示します。

01canvas.drawColor(Color.BLUE);
02 
03Bitmap bitmap;
04Canvas bitmapCanvas;
05Paint paint = new Paint();
06paint.setColor(Color.GREEN);
07 
08// Bitmapを新規に作成し、そのBitmapのCqanvasに円を描いて表示する。
09bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
10bitmapCanvas = new Canvas(bitmap);
11bitmapCanvas.drawColor(Color.BLACK);
12bitmapCanvas.drawCircle(50, 50, 40, paint);
13canvas.drawBitmap(bitmap, 10, 10, null);
14 
15// 既存のBitmapのコピーを作成し、そのBitmapのCqanvasに円を描いて表示する。
16bitmap = BitmapFactory
17        .decodeResource(getResources(), R.drawable.sample);
18if (!bitmap.isMutable()) {
19    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
20}
21 
22bitmapCanvas = new Canvas(bitmap);
23bitmapCanvas.drawCircle(50, 50, 40, paint);
24canvas.drawBitmap(bitmap, 10, 120, null);

18行目のisMutableメソッドは、Bitmapが変更可能かどうかを返します。

Bitmapが変更可能でない場合に、変更可能なコピーを作成して、これに描画しています。

9行目のcreateBitmapメソッドと、19行目のcopyメソッドの引数、Bitmap.Config.ARGB_8888は、 32ビットのARGBデータでBitmapを作成する事を、示しています。

Color値は32ビットのARGBデータですので、通常、このBitmap.Config.ARGB_8888を指定して、Bitmapを作成します。

enum型Bitmap.Configは、Bitmapのピクセルフォーマットを指定するもののようで、他にもALPHA_8,ARGB_4444,RGB_565があり、 それぞれBitmapがARGBの各値に何ビット使用するかを、示しているようです。

 

22行目~24行目は、BitmapオブジェクトのCanvasオブジェクトを作成し、bitmapCanvas変数に代入して、このbitmapCanvasに対して、すなわちBitmap内に、円を描画した後、 そのBitmapをViewのCanvasに描画しています。

余談ですが、CanvasクラスにはsetBitmapメソッドもあります。

setBitmapメソッドを使うと、上記プログラムの22行目は、以下のコードに置き換えることができます。

1bitmapCanvas = new Canvas();
2bitmapCanvas.setBitmap(bitmap);

 

このプログラムを実行すると、以下のように画像が表示されます。

 

 

Bitmapオブジェクトの、新規作成とコピーのためのメソッドは幾つかあります。

以下に、その書式を列挙します。

  • Bitmap copy(Bitmap.Config config, boolean isMutable)
  • static Bitmap createBitmap(Bitmap src)
  • static Bitmap createBitmap(int[] colors, int width, int height, Bitmap.Config config)
  • static Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, Bitmap.Config config)
  • static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
  • static Bitmap createBitmap(int width, int height, Bitmap.Config config)
  • static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height)
  • static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)

ピクセルによるBitmapの画像の加工

Bitmapクラスには、Bitmapのピクセルデータを取得,設定するメソッドが用意されています。

以下のプログラムは、Bitmapのピクセルデータを取得して、ピクセルデータに修正を加えて、表示するサンプルです。

01Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
02 
03if (!bitmap.isMutable()) {
04    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
05}
06 
07int width = bitmap.getWidth();
08int height = bitmap.getHeight();
09int[] pixels = new int[width * height];
10 
11bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
12 
13for (int y = 0; y < height; y++) {
14    for (int x = 0; x < width; x++) {
15        pixels[x + y * width] ^= 0x00ffffff;
16    }
17}
18 
19bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
20canvas.drawBitmap(bitmap, 0, 0, new Paint());

ピクセルデータのRGBの値の各ビットの反転を行っています。

getPixelsメソッド,setPixelsメソッドの引数の意味については 、 「 しずくくんのAndroidでゲームプログラミングしてみたいなblog - Bitmap.getPixels()のstride引数の意味がわかった」 が参考になります。

このプログラムを実行すると、以下のような画面が表示されます。

 

 

このプログラムは、drawBitmapのオーバロードされたメソッドを使って、以下のように記述する事も可能です。

01Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
02 
03if (!bitmap.isMutable()) {
04    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
05}
06 
07int width = bitmap.getWidth();
08int height = bitmap.getHeight();
09int[] pixels = new int[width * height];
10 
11bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
12 
13for (int y = 0; y < height; y++) {
14    for (int x = 0; x < width; x++) {
15        pixels[x + y * width] ^= 0x00ffffff;
16    }
17}
18 
19canvas.drawBitmap(pixels, 0, width, 10, 10, width, height, true, null);

Matrixの操作によるBitmap画像の加工

Matrixオブジェクトを操作すると、Bitmap画像の回転やスケールの変更等の、操作をおこなう事ができます。

以下に、そのプログラムの例を示します。

01Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.sample);
02int width = bitmap.getWidth();
03int height = bitmap.getHeight();
04 
05Bitmap bitmap2;
06Matrix matrix;
07 
08// Bitmapを45度回転
09matrix = new Matrix();
10matrix.postRotate(45);
11bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
12canvas.drawBitmap(bitmap2, 0, 0, null);
13 
14// Bitmapの縦横の長さを半分変更
15matrix = new Matrix();
16matrix.postScale(0.5f, 0.5f);
17bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
18canvas.drawBitmap(bitmap2, 0, 0, null);
19 
20// Bitmapの左右を逆に変更
21matrix = new Matrix();
22matrix.preScale(-1, 1);
23bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
24canvas.drawBitmap(bitmap2, width / 2, height / 2, null);

 

MatrixのpostRotateメソッドを使うと、Bitmapオブジェクトを回転させることができます。

postScaleメソッドを使うと、スケールを変更することができます。

 

このプログラムを実行すると、以下のような画面が表示されます。

 

 

ImageViewウィジェットによるBitmapの描画

ウィジェットを使って、ActivityにBitmapを描画する事もできます。

以下に、そのプログラムの例を示します。

01package gudon.sample.imageview;
02 
03import android.app.Activity;
04import android.graphics.Bitmap;
05import android.graphics.BitmapFactory;
06import android.os.Bundle;
07import android.widget.ImageView;
08 
09public class ImageViewSample extends Activity {
10 
11    @Override
12    public void onCreate(Bundle savedInstanceState) {
13        super.onCreate(savedInstanceState);
14        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
15        ImageView imageView = new ImageView(this);
16        imageView.setImageBitmap(bitmap);
17 
18        setContentView(imageView);
19    }

その他

Bitmapを描画するには、他にもDrawableを使う手もあります。

これについては、グラフィックス(7)-Drawableによる描画を参照して下さい。

Bitmap#compressメソッドを使って、JPEG,PNGファイルとして保存する事もできるようです。

参考URL

 

ページのトップへ戻る