1. 程式人生 > >Android-載入大圖片

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

 


 

效果圖: