前回に続き 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を経由させる必要は、ありません。(笑い)