Android-加载大图片

在开发之中会遇到,加载小图片没问题,当加载大图片的时候,内存溢出,为了解决这个问题,Android是提供了API 来处理优化图片的方式解决,就是计算屏幕宽高 和 图片宽高 的缩放比例,进行缩放,这样就不会报内存溢出错误来

  

activity_image.xml 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="readImageMin"
        android:text="读取Sdcard的小图片"
        android:layout_alignParentBottom="true"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="readImageMax"
        android:text="读取Sdcard的大图片"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        />

</RelativeLayout>

 

MyImageActivity.java

package liudeli.my_media1;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.Display;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;

public class MyImageActivity extends Activity {

    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_image);

        imageView = findViewById(R.id.image_view);
    }

    /**
     * 读取Sdcard小图片
     * @param view
     */
    public void readImageMin(View view) {
        File file = new File(Environment.getExternalStorageDirectory(), "mm.jpg");
        if (!file.exists()) {
            Toast.makeText(this, file.getName() + "不存在", Toast.LENGTH_SHORT).show();
            return;
        }
        /**
         * 通过BitmapFactory,去decodeFile加载图片
         */
        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
        imageView.setImageBitmap(bitmap);
    }

    /**
     * 读取Sdcard的大图片
     * @param view
     */
    public void readImageMax(View view) {

        /**
         * >>>>>>>> 第一步:只获取图片的宽和高
         */
        BitmapFactory.Options options = new BitmapFactory.Options();

        // 设置只获取图片的信息,到时候记得还原恢复成false
        options.inJustDecodeBounds = true;

        /*
         * 第一次加载图片,只为获得宽高
         */
        BitmapFactory.decodeFile("/sdcard/big.JPG", options);

        // 获取图片的宽高
        int outWidth = options.outWidth;
        int outHeight = options.outHeight;

        /**
         * >>>>>>>> 第二步:获取屏幕的宽和高
         */

        // 获取手机屏幕的宽高,手机屏幕属于Window
        Display display = getWindow().getWindowManager().getDefaultDisplay();
        int windowWidth = display.getWidth();
        int windowHeight = display.getHeight();

        /**
         * >>>>>>>> 第三步:图片宽和高 对比 屏幕宽和高 = 计算宽高的缩放比例
         */

        /*
         * 计算宽高的缩放比例
         * valueX 代表横行 宽
         * valueY 代表纵向 高
         */
        int valueX = outWidth / windowWidth;
        int valueY = outHeight / windowHeight;

        /**
         * 判断宽和高的缩放比例哪个大,哪个大我就取哪个的值,只要把大的值处理即可
         */
        int value = valueX > valueY ? valueX : valueY;

        // 防止加载的图片,比屏幕小,如果比屏幕小,就没有必要缩放了
        if (0 >= value) {
            value = 1;
        }

        // 在这里要恢复options.inJustDecodeBounds,才能设置下面的代码,设置false需要加载图片内容啦
        options.inJustDecodeBounds = false;

        // 指定缩放比率
        options.inSampleSize = value;

        /**
         * 参数一:不推荐/sdcard/big.JPG 这种方式,因为每部手机的这个路径会变的,所以开发中要用Environment
         * 参数二:Options 选项 可以设置图片的比例缩放,从而解决图片内存溢出的问题
         */
        Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/big.JPG", options);
        imageView.setImageBitmap(bitmap);
    }
}

 

Android提供的BitmapFactory这个类,身上有个 decodeFile方法,参数一:加载要现实的图片地址,  参数二:Options 选项 可以设置图片的比例缩放,从而解决图片内存溢出的问题 

Android系统源码 BitmapFactory.java 的 decodeFile方法:

public static Bitmap decodeFile(String pathName, Options opts)

 

如果加载大图片,不使用Options来处理,会报内存溢出OutOfMemoryError

Android-加载大图片

 


 

效果图:

Android-加载大图片

 

Android-加载大图片

上一篇:iOS 获取本地语言


下一篇:杂记:解决Android扫描BLE设备名称不刷新问题