Android BitMapの最適化


ImageViewを使用してbitmapを表示すると、特に画像が大きい場合、クラッシュを招く可能性があります.
BitmapFactory.Optionsを使用してinSampleSizeを設定することで、システムリソースの要件を軽減できます.
属性値inSampleSizeは、サムネイルサイズが元のピクチャサイズの数分の1を表します.すなわち、この値が2の場合、取り出したサムネイルの幅と高さは元のピクチャの1/2であり、ピクチャサイズは元のサイズの1/4です.
OptionsにはinJustDecodeBoundsという属性がありますが、SDKではこう言います
If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.
InJustDecodeBoundsをtrueに設定し、outHeight(画像の元の高さ)とoutWidth(画像の元の幅)を取得し、inSampleSize(スケール値)を計算します.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ImageView
android:id="@+id/imageview"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
/>
</LinearLayout>

JAvaソース
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;
 
public class AndroidImage extends Activity {
 
private String imageFile = "/sdcard/AndroidSharedPreferencesEditor.png";
/** Called when the activity is first created. */
 
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
   
ImageView myImageView = (ImageView)findViewById(R.id.imageview);
//Bitmap bitmap = BitmapFactory.decodeFile(imageFile);
//myImageView.setImageBitmap(bitmap);
 
Bitmap bitmap;
float imagew = 300;
float imageh = 300;
 
BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();
bitmapFactoryOptions.inJustDecodeBounds = true;
bitmap = BitmapFactory.decodeFile(imageFile, bitmapFactoryOptions);
 
int yRatio = (int)Math.ceil(bitmapFactoryOptions.outHeight/imageh);
int xRatio = (int)Math.ceil(bitmapFactoryOptions.outWidth/imagew);
 
if (yRatio > 1 || xRatio > 1){
 if (yRatio > xRatio) {
  bitmapFactoryOptions.inSampleSize = yRatio;
  Toast.makeText(this,
    "yRatio = " + String.valueOf(yRatio),
    Toast.LENGTH_LONG).show();
 }
 else {
  bitmapFactoryOptions.inSampleSize = xRatio;
  Toast.makeText(this,
    "xRatio = " + String.valueOf(xRatio),
    Toast.LENGTH_LONG).show();
 }
}
else{
 Toast.makeText(this,
   "inSampleSize = 1",
   Toast.LENGTH_LONG).show();
}
 
bitmapFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(imageFile, bitmapFactoryOptions);
myImageView.setImageBitmap(bitmap);
}
 
}