前回に続き OpenCvに直接関わらない話題だが、大きな画像を読み込んで画面に表示したり サムネールとして複数の画像を一緒に表示する際、無駄なメモリを使わないように 読み込む段階で 小さくして読むクラスを作成しました。
hoge256さんの AndroidでBitmapFactoryを使ってサイズの大きな画像を読み込むサンプルを参考にさせて いただきました。ありがとうございます。
作ったクラス
package jp.ne.dazoo.nobotta;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class ResizeLoad {
public Bitmap bmpLoad(String path,int width,int height){
Bitmap bmp = null;
//読み込み用のオプションオブジェクトを生成
BitmapFactory.Options opt = new BitmapFactory.Options();
//この値をtrueにすると実際には画像を読み込まず、
//画像のサイズ情報だけを取得することができます。
opt.inJustDecodeBounds = true;
//画像ファイル読み込み
//ここでは上記のオプションがtrueのため実際には画像は読み込まれません。
BitmapFactory.decodeFile(path, opt);
//読み込んだサイズはoptions.outWidthとoptions.outHeightに
//格納されるので、その値から読み込む際の縮尺を計算します。
int scaleW = opt.outWidth / width + 1;
int scaleH = opt.outHeight / height + 1;
//縮尺は整数値で、2なら画像の縦横のピクセル数を1/2にしたサイズ。
//3なら1/3にしたサイズで読み込まれます。
int scale = Math.max(scaleW, scaleH);
//今度は画像を読み込みたいのでfalseを指定
opt.inJustDecodeBounds = false;
//先程計算した縮尺値を指定
opt.inSampleSize = scale;
//これで指定した縮尺で画像を読み込めます。
bmp = BitmapFactory.decodeFile(path, opt);
return bmp;
}
}
メイン側
public class OpenCVnyumonActivity extends Activity {
ImageView imgv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String path=Environment.getExternalStorageDirectory()+"/DCIM/100ANDRO/dsc002.jpg"; <---これが大きい
// 画面サイズを取得する
Matrix matrix = new Matrix();
DisplayMetrics metrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
ResizeLoad rsl = new ResizeLoad();
Bitmap src = (rsl.bmpLoad(path, screenWidth, screenHeight)).copy(Bitmap.Config.ARGB_8888, true);
Mat mat = android.BitmapToMat(src);
src.recycle();
Bitmap dsc= Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888);
android.MatToBitmap(mat, dsc);
imgv = (ImageView)findViewById(R.id.imageView1);
imgv.setImageBitmap(dsc);
}
}
この例では 画面全体のサイズを最大サイズに指定しています。しかし読む込むサイズは 元サイズの1/n のため 画面ぴったりにはなりません。ぴったりにするには 読み込んだ後 Resizeする必要があります。
お断り この処理では 特にMatを経由させる必要は、ありません。(笑い)