2011年6月2日木曜日

大きな画像をリサイズして読み込む方法の備忘録

Androidで大きなサイズの画像をリサイズしながら取得する方法として
先日、どちらかのブログで紹介されていたものです。
BitmapFactoryを活用することで、画像をロードする前に画像の情報だけを取得し、
inSampleSizeへスケーリングサイズを指定することでリサイズした画像を取得しています。

掲載元からコピペ、関数名等を自分好みに修正して活用させていただいていますが、
掲載先のブログが分からなくなってしまったため、
備忘用にメモします。

/**
* リサイズ済み画像を取得する。
* @param file 画像ファイル
* @param view_width 目的のサイズ(幅)
* @param view_height 目的のサイズ(高さ)
* @return
*/
public Bitmap getResizeBitmap(File file, int view_width, int view_height){
Bitmap ret = null;

if(file == null){
}else{
//画像
BitmapFactory.Options option = new BitmapFactory.Options();
Bitmap src = null;
int sample_size = 0;

//実際に読み込まないで情報だけ取得する
option.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), option);
if((option.outWidth * option.outHeight) > 1048576){
//1Mピクセル超えてる
double out_area = (double)(option.outWidth * option.outHeight) / 1048576.0;
sample_size = (int) (Math.sqrt(out_area) + 1);
}else{
//小さいのでそのまま
sample_size = 1;
}

//実際に読み込むモード
option.inJustDecodeBounds = false;
//スケーリングする係数
option.inSampleSize = sample_size;
//画像を読み込む
src = BitmapFactory.decodeFile(file.getAbsolutePath(), option);
if(src == null){
}else{
int src_width = src.getWidth();
int src_height = src.getHeight();

//表示利用域に合わせたサイズを計算
float scale = getFitScale(view_width, view_height, src_width, src_height);

//リサイズマトリクス
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);

//ビットマップ作成
ret = Bitmap.createBitmap(src, 0, 0, src_width, src_height, matrix, true);
}
}

return ret;
}

/**
* 最適なスケールを求める
* @param dest_width 目的のサイズ(幅)
* @param dest_height 目的のサイズ(高さ)
* @param src_width 元のサイズ(幅)
* @param src_height 元のサイズ(高さ)
* @return
*/
public static float getFitScale(int dest_width, int dest_height
, int src_width, int src_height){
float ret = 0;

if(dest_width < dest_height){ //縦が長い if(src_width < src_height){ //縦が長い ret = (float)dest_height / (float)src_height; if((src_width * ret) > dest_width){
//縦に合わせると横がはみ出る
ret = (float)dest_width / (float)src_width;
}
}else{
//横が長い
ret = (float)dest_width / (float)src_width;
}
}else{
//横が長い
if(src_width < src_height){ //縦が長い ret = (float)dest_height / (float)src_height; }else{ //横が長い ret = (float)dest_width / (float)src_width; if((src_height * ret) > dest_height){
//横に合わせると縦がはみ出る
ret = (float)dest_height / (float)src_height;
}
}
}

return ret;
}

Reference Link