1. 程式人生 > >Android圖片質量壓縮以及縮圖生成

Android圖片質量壓縮以及縮圖生成

1、圖片的質量壓縮

圖片的質量壓縮是指,僅僅壓縮圖片檔案的大小,但當圖片載入到記憶體中時,佔用的記憶體大小並沒有太大變化。可以通過質量壓縮,加快圖片上傳的速度。

程式碼如下:

/**
*將檔案壓縮後覆蓋原始檔
*/
public static void compressImage(File file) {
Bitmap bitmap=BitmapFactory.decodeFile(file.getAbsolutePath());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 80
, baos);// 質量壓縮方法,這裡100表示不壓縮,把壓縮後的資料存放到baos中 int options = 80;//先壓縮到80% while (baos.toByteArray().length / 1024 > 200) { // 迴圈判斷如果壓縮後圖片是否大於200kb,大於繼續壓縮 if (options <= 0) {//有的圖片過大,可能當options小於或者等於0時,它的大小還是大於目標大小,於是就會發生異常,異常的原因是options超過規定值。所以此處需要判斷一下 break; } baos.reset();// 重置baos即清空baos
options -= 10;// 每次都減少10 bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); } try { FileOutputStream fos = new FileOutputStream(file); fos.write(baos.toByteArray()); fos.close(); baos.close(); } catch
(Exception e) { e.printStackTrace(); } }

通過上述程式碼,可以將2.5M的圖片壓縮到200KB左右,並且圖片的清晰度差別不大,但是需要注意的是,這改變的只是圖片檔案的大小,並不能改變載入此圖片的記憶體大小。所以對於此類圖片,在載入的時候也是需要注意的,避免OOM異常。需要注意的是,上述程式碼執行時,還是需要時間的,所以最好放在子執行緒中執行。


2、縮圖生成

縮圖生成的圖片會改變記憶體佔用的大小,所以一般不需要顯示全圖情況,可以用縮圖去展示,減少程式記憶體損耗。

程式碼如下:

    /**
     * 獲取縮圖
     * @param imagePath:檔案路徑
     * @param width:縮圖寬度
     * @param height:縮圖高度
     * @return
     */
    public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; //關於inJustDecodeBounds的作用將在下文敘述
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
        int h = options.outHeight;//獲取圖片高度
        int w = options.outWidth;//獲取圖片寬度
        int scaleWidth = w / width; //計算寬度縮放比
        int scaleHeight = h / height; //計算高度縮放比
        int scale = 1;//初始縮放比
        if (scaleWidth < scaleHeight) {//選擇合適的縮放比
            scale = scaleWidth;
        } else {
            scale = scaleHeight;
        }
        if (scale <= 0) {//判斷縮放比是否符合條件
            be = 1;
        }
        options.inSampleSize = scale;
        // 重新讀入圖片,讀取縮放後的bitmap,注意這次要把inJustDecodeBounds 設為 false
                options.inJustDecodeBounds = false;
                bitmap = BitmapFactory.decodeFile(imagePath, options);
        // 利用ThumbnailUtils來建立縮圖,這裡要指定要縮放哪個Bitmap物件
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }

通過上述程式碼載入圖片的縮圖,將會有效的避免OOM異常。在這裡需要解釋下options.inJustDecodeBounds這個屬性,當options.inJustDecodeBounds設定為true時,通過BitmapFactory.decodeFile去載入圖片,將不會正真地返回bitmap,也就是說此時的bitmap為null。它的作用是將圖片的相關資訊,例如圖片寬高,大小等資訊帶到options中,方便我們後續計算圖片的寬高比。

當我們計算好寬高比後,通過options.inSampleSize來設定縮放比例,然後將options.inJustDecodeBounds的值設定為false,再通過BitmapFactory.decodeFile去載入圖片就能獲取真正的bitmap物件了。最後通過ThumbnailUtils.extractThumbnail來獲取最終的縮圖。需要說明的是,ThumbnailUtils.OPTIONS_RECYCLE_INPUT表示回收建立縮圖時的資源。

或許有的朋友覺得既然已經通過BitmapFactory.decodeFile的方式處理過了,為什麼還需要ThumbnailUtils.extractThumbnail來再處理一次呢。首先,僅僅通過之前的處理,最終的縮圖的寬高還是和我們設定的大小有點出入的,所以用ThumbnailUtils再處理一次。可能又會有人說了,為什麼不直接使用ThumbnailUtils來生成縮圖呢?因為使用ThumbnailUtils是需要傳入bitmap的,試問有沒有這樣的情況,圖片太大,導致在載入圖片的時候直接就OOM了,那還怎麼使用ThumbnailUtils呢?

本人Android菜鳥一枚,如有錯誤,歡迎指正,謝謝大家!