Android设置采样率高效加载图片

使用BitmapFactory.Options中的inSampleSize(采样率)参数来缩放加载图片是提高加载效率的核心思想。

步骤为

  1. 将BitmapFactory.Options的inJustDecodeBounds参数设为ture来预加载图片。
  2. 从Options读取出图片的原始宽高值,对应outWidth和outHeight参数。
  3. 结合所需要显示的大小计算合适的采样率inSampleSize值。
  4. 将Options中的inJustDecodeBounds参数设置false,重新加载图片资源即可。

通过加载一张高清图来说明设置采样率的效果

  • 准备一张高清图放到drawable目录下:
    这里写图片描述
    Android设置采样率高效加载图片_第1张图片

  • 布局代码(一个ImageView+两个水平按钮)


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/img"
        android:layout_width="400dp"
        android:layout_height="300dp" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加载原图" />

        <Button
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="使用预加载" />
    LinearLayout>
LinearLayout>
  • MainActivity代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ImageView mImg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImg = (ImageView) findViewById(R.id.img);


        findViewById(R.id.btn1).setOnClickListener(this);
        findViewById(R.id.btn2).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn1: //普通设置图片
                mImg.setImageResource(R.drawable.mm);
                break;
            case R.id.btn2://重新计算采样率加载图片
                mImg.setImageBitmap(BitmapOptionLoadUtil.decodeBitmapFromResource(getResources(),
                        R.drawable.mm,
                        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 400, getResources().getDisplayMetrics()),
                        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, getResources().getDisplayMetrics())));
                break;
        }
    }
}
  • BitmapOptionLoadUtil代码(和上步所说的步骤一样)
public class BitmapOptionLoadUtil {

    /**
     * 缩放加载图片
     *
     * @param res
     * @param resId
     * @param decodeWidth
     * @param decodeHeight
     * @return
     */
    public static Bitmap decodeBitmapFromResource(Resources res, @IdRes int resId, int decodeWidth, int decodeHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; //预加载
        BitmapFactory.decodeResource(res, resId, options);

        final int imgWidth = options.outWidth; //要加载的图片的宽
        final int imgHeight = options.outHeight;//要加载的图片的高

        int inSampleSize = 1;

        if (imgWidth > decodeWidth || imgHeight > decodeHeight) {
            int halfWidth = imgWidth / 2;
            int halfHeight = imgHeight / 2;

            while ((halfWidth / inSampleSize) >= decodeWidth &&
                    (halfHeight / inSampleSize) >= decodeHeight) {
                inSampleSize *= 2;
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;

        return BitmapFactory.decodeResource(res, resId, options);
    }
}
  1. 运行程序,点击加载原图
    这里写图片描述
    通过IDE可以看到加载原图后分配的内存高达36.76M!
    2.重新运行程序,点击使用预加载
    这里写图片描述
    可以看到比直接加载原图分配的内存少了2倍还多。可见设置合理的采样率可以高效的加载图片。

你可能感兴趣的:(Android)