Bitmapを使う時は結構あったのですが、まとめてなかったので少しBitmapの利用の仕方をまとめてみます。
はじめにbitmapの取得の方法をいくつか、うしろの方で、bitmapの使い方をいくつか紹介してます。
drawableの画像データを利用
自分でアプリ内に埋め込んだ画像の取得です。
Bitmap bitmap0 = BitmapFactory.decodeResource(getResources(),R.drawable.background);
SDCARDからファイルを参照
bitmapに変換された状態で、java内部で利用する事になります。streamで読む場合はbyteなどになっていますが。
BitmapFactory.decodeFile("file:///***.jpg");
画像をスライドショーとして表示する。画像のファイルを読み込む
ギャラリーから参照
写真一覧表示のアプリが標準で入っていると思いますが、そのアプリを使って、一覧の中から画像を取得できます。
【ライブラリ呼び出し】
Intent intent = new Intent(); intent.setType("image/*"); searchPict = true; intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, REQUEST_GALLERY);
【取得】
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if(requestCode == REQUEST_GALLERY && resultCode == RESULT_OK) { try { InputStream in = getContentResolver().openInputStream(data.getData()); Bitmap bmp = BitmapFactory.decodeStream(in); in.close(); }catch(Error e){} } }
参考:Androidプログラマへの道 ~ Moonlight 明日香 ~
URLから読み込む
HttpURLConnectionを使います。個人的に外部読み込みは非同期の中に下記かなーと思います。
try { URL url = new URL(_url); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream input = connection.getInputStream(); Bitmap myBitmap = BitmapFactory.decodeStream(input); return myBitmap; } catch (IOException e) { e.printStackTrace(); return null; }
参照:URL から Bitmap を 取得 ( 変換 )する方法
VIEWから読み込む
キャッシュ機能がviewにあってデフォルトでオフになっているので、bitmapを取得の時のみオンにして利用をしてキャプチャをとります。
_view.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(_view.getDrawingCache()); _view.setDrawingCacheEnabled(false);
上記のような形で、プログラム内でJAVAを利用する事が非常に多いです。また、bitmapは非常に扱いやすく、変形や、変更などを行う機能も充実しています。
下記からは、bitmapの利用の方法についてまとめてます。
縮小
画像サイズの変更に関しては、Matrixを使って、サイズの縮小を行う。
長い方を200に収める。
int w = bmp.getWidth(); int h = bmp.getHeight(); float scale = Math.min((float)200/w, (float)200/h); Matrix matrix = new Matrix(); matrix.postScale(scale, scale); Bitmap bmp2 = Bitmap.createBitmap(bmp, 0, 0, w, h, matrix, true);
createbitmapの最後のbooleanは、[filter]のon/offのようですが、trueにしておくと、
少しアンチエイリアスがかかるようです。
ビットマップの書き換えなので、特には正方形にトリミングとかも結構カンタンにできる。
正方形トリミングかつ。中央寄せ。
int w = bmp.getWidth(); int h = bmp.getHeight(); float scale = Math.max((float)200/w, (float)200/h); int size = Math.min(w, h); Matrix matrix = new Matrix(); matrix.postScale(scale, scale); Bitmap bmp2 = Bitmap.createBitmap(bmp, (w-size)/2, (h-size)/2, size, size, matrix, true);
操作と言うよりもbitmapを利用して新しいbitmapの作成と言うイメージです。
回転
bitmapでのマトリックスは回転などもできます。
Matrix matrix = new Matrix(); matrix.postRotate(45); Bitmap bmp2 = Bitmap.createBitmap(bmp, 0, 0, size, size, matrix, true);
縮小と同じタイミングでmatrixに設定もできます。
メモリの開放
matrixを利用した方法だと新たなbitmapを作成するので、元のデータのメモリは開放していましましょう。
bmp.recycle(); bmp = null;
(recycleはメモリ開放対象と言うもので必ずしもすぐに開放と言う訳ではないようです。)
で開放される。ただし、開放に関しては、
もし、bitmapを他のImageViewなどでdrawableとして利用していた場合には、その設定を解除してあげないと、参照は終わらないらしいです。
image.setImageDrawable(null);
ImageViewには、直接bitmapを指定する事もできるのですが、上記で利用したdrawableのクラスは割と汎用性が高く直接bitmapをいじらずに利用ができるみたいです。
Drawable
Drawableは直接、データをいじらずに、明るさを変えたり大きさを変えたりできます。
※今回は扱う範囲の問題もあるので、下記のサイトの紹介で終えさせていただきます。
色データの取得
Bitmapは絵のデータ。を利用と言う間隔で色のデータをピクセル単位で取得する事ができます。
int width = bmp.getWidth(); int height = bmp.getHeight(); int[] pixels = new int[width * height]; bmp.getPixels(pixels, 0, width, 0, 0, width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { pixels[x + y * width]//(x,y)の部分の色のデータ } } bmp.setPixels(pixels, 0, width, 0, 0, width, height);
setPixelと言う関数もあって、使い易いのですが、
速度の問題で、setPixelsをつかった方がよいようです。
Bitmap.setPixel()をsetPixels()に変えたら3倍速くなったよ
byteArrayとして扱う
bitmapを保有している場合、簡単にbytearrayを利用できます。
ByteArrayOutputStream bos = new ByteArrayOutputStream(); bmp2.compress(CompressFormat.JPEG, 90, bos); bos.flush(); byte[] _bArray = bos.toByteArray(); bos.close();
上記では、データ自体をjpegに圧縮をしていますが、この状態にすればSDCARDに保存ができます。
_imagePath = Environment.getExternalStorageDirectory().getPath() + "/bmp.jpg"; try { foStream = new FileOutputStream(_imagePath); foStream.write(_bArray); foStream.close(); }catch(Error e){}
画像の保存に関しては、ギャラリーに認識させたりする場合などは下記より参照してください。
(※デフォルトの機能だと再起動などしない限り画像が参照されません。)
BASE64エンコードする
サーバーに画像のデータを送る場合にBASE64エンコードしてStringとして送る場合には
下記のようにできます。(ByteArrayを利用)
ByteArrayOutputStream bos = new ByteArrayOutputStream(); bmp2.compress(CompressFormat.JPEG, 90, bos); byte[] _bArray = bos.toByteArray(); String image64 = Base64.encodeToString(_bArray, Base64.DEFAULT); _imageBinary = "data:image/jpeg;base64,"+image64;
メールなど他のアプリで画像を送る
上記に関しては、bitmapでは、結局無理だったという、個人の見解で一旦保存して、そのpathを送りましょうというのが現段階です。
他の機能
シェーダーとして塗りに利用
Matrix offset for tiled BitmapDrawable
鏡面反射
などなどで、ちょっと長くなってしまいましたが、取り急ぎ、必要そうなデータをまとめさせていただきました。
追記—
便利そうなものを作ってる人がいたのでメモです。