1. 程式人生 > >Android壓縮圖片到100K以下並保持不失真的高效方法

Android壓縮圖片到100K以下並保持不失真的高效方法

 在開發Android企業應用時,會經常上傳圖片到伺服器,而我們公司目前維護的一個專案便是如此。該專案是通過私有apn與伺服器進行互動的,聯通的還好,但移動的速度實在太慢,客戶在使用軟體的過程中,由於上傳的資訊中可能包含多張圖片,會經常出現上傳圖片失敗的問題,為了解決這個問題,我們決定把照片壓縮到100k以下,並且保證圖片不失真(目前圖片經過壓縮後,大約300k左右)。於是我就重新研究了一下Android的圖片壓縮技術。

Android端目錄結構如下圖所示:





使用的第三方庫jar包,如下圖所示:

其中ksoap2-android-xxx.jar是Android用來呼叫webservice的,gson-xx.jar是把JavaBean轉成Json資料格式的。
本篇部落格主要講解圖片壓縮的,核心程式碼如下:

//計算圖片的縮放值
public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
             final int heightRatio = Math.round((float) height/ (float) reqHeight);
             final int widthRatio = Math.round((float) width / (float) reqWidth);
             inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
        return inSampleSize;
}

// 根據路徑獲得圖片並壓縮,返回bitmap用於顯示
public static Bitmap getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, 480, 800);

        // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(filePath, options);
    }

//把bitmap轉換成String
public static String bitmapToString(String filePath) {

        Bitmap bm = getSmallBitmap(filePath);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 40, baos);
        byte[] b = baos.toByteArray();
        return Base64.encodeToString(b, Base64.DEFAULT);
    }

壓縮原理講解:壓縮一張圖片。我們需要知道這張圖片的原始大小,然後根據我們設定的壓縮比例進行壓縮。
這樣我們就需要做3件事:
1.獲取原始圖片的長和寬

 BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
                int height = options.outHeight;
            int width = options.outWidth; 

以上程式碼是對圖片進行解碼,inJustDecodeBounds設定為true,可以不把圖片讀到記憶體中,但依然可以計算出圖片的大小,這正好可以滿足我們第一步的需要。
2.計算壓縮比例
 int height = options.outHeight;
     int width = options.outWidth; 
     int inSampleSize = 1;
     int reqHeight=800;
     int reqWidth=480;
     if (height > reqHeight || width > reqWidth) {
    final int heightRatio = Math.round((float) height/ (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);            
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
     }

一般手機的解析度為 480*800 ,所以我們壓縮後圖片期望的寬頻定為480,高度設為800,這2個值只是期望的寬度與高度,實際上壓縮後的實際寬度也高度會比期望的要大。如果圖片的原始高度或者寬頻大約我們期望的寬頻和高度,我們需要計算出縮放比例的數值。否則就不縮放。heightRatio是圖片原始高度與壓縮後高度的倍數,widthRatio是圖片原始寬度與壓縮後寬度的倍數。inSampleSize為heightRatio與widthRatio中最小的那個,inSampleSize就是縮放值。 inSampleSize為1表示寬度和高度不縮放,為2表示壓縮後的寬度與高度為原來的1/2
3.縮放並壓縮圖片
 //在記憶體中建立bitmap物件,這個物件按照縮放大小建立的
             options.inSampleSize = calculateInSampleSize(options, 480, 800);
        options.inJustDecodeBounds = false;
        Bitmap bitmap= BitmapFactory.decodeFile(filePath, options);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 60, baos);
        byte[] b = baos.toByteArray();

前3行的程式碼其實已經得到了一個縮放的bitmap物件,如果你在應用中顯示圖片,就可以使用這個bitmap物件了。由於考慮到網路流量的問題。我們好需要犧牲圖片的質量來換取一部分空間,這裡呼叫bm.compress()方法進行壓縮,這個方法的第二個引數,如果是100,表示不壓縮,我這裡設定的是60,你也可以更加你的需要進行設定,在實驗的過程中我設定為30,圖片都不會失真。

壓縮效果:本demo可以把1.5M左右的圖片壓縮到100K左右,並且沒有失真。
效果圖如下:
demo.jpg

更新:

/*
壓縮圖片,處理某些手機拍照角度旋轉的問題
*/
public static String compressImage(Context context,String filePath,String fileName,int q) throws FileNotFoundException {

        Bitmap bm = getSmallBitmap(filePath);

        int degree = readPictureDegree(filePath);

        if(degree!=0){//旋轉照片角度
            bm=rotateBitmap(bm,degree);
        }

        File imageDir = SDCardUtils.getImageDir(context);

        File outputFile=new File(imageDir,fileName);

        FileOutputStream out = new FileOutputStream(outputFile);

        bm.compress(Bitmap.CompressFormat.JPEG, q, out);

        return outputFile.getPath();
    }

判斷照片角度
public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degree = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degree = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degree = 270;
                break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

旋轉照片
public static Bitmap rotateBitmap(Bitmap bitmap,int degress) {
        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress); 
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }



相關推薦

Android壓縮圖片100K以下保持失真高效方法

 在開發Android企業應用時,會經常上傳圖片到伺服器,而我們公司目前維護的一個專案便是如此。該專案是通過私有apn與伺服器進行互動的,聯通的還好,但移動的速度實在太慢,客戶在使用軟體的過程中,由於上傳的資訊中可能包含多張圖片,會經常出現上傳圖片失敗的問題,為了解決這個

android 壓縮圖片壓縮100K以下,並且寬高超過1028

在android開發中,經常遇到圖片壓縮問題,由此記錄下以下壓縮方法。 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import and

上傳壓縮後的圖片並且保持100k失真方法

壓縮100k圖片不失真的方法;先獲取圖片的原始長度和寬度;然後計算圖片的縮放值;最後等比例壓縮; 下面程式碼是壓縮的工具類; public class PictureUtil { /** * 主方法 * * @param filePath * @r

Xamarin.Android 壓縮圖片上傳到WebServices

越來越大 () exists jpeg color 文件寫入 data pen map   隨著手機的拍照像素越來越高,導致圖片贊的容量越來越大,如果上傳多張圖片不進行壓縮、質量處理很容易出現OOM內存泄漏問題。   最近做了一個項目,向webservices上傳多張照片,

android -------- 壓縮圖片檔案工具類

專案中常常遇到檔案壓縮問題,上傳檔案大小限制 今天簡單的分享一點乾貨,檔案壓縮,圖片壓縮,壓縮Bitmap 主要通過尺寸壓縮和質量壓縮,以達到清晰度最優   效果圖              原始碼地址: 

java壓縮圖片記憶體大小,但改變解析度大小,第一種方式

/*** @Title: compressPicByQuality * @Description: 壓縮圖片,通過壓縮圖片質量,保持原圖大小* @param  quality:0-1* @return byte[] * @throws*/public static byte

Android壓縮圖片並且儲存到本地記憶體卡中

        親愛的同學們,相信我們在軟體開發中經常會遇到拍照,選擇相簿上傳的功能。前幾天遇到一個這樣的一個問題。後臺要求我上傳的圖片不能超過500KB,大家知道我們現在的智慧手機畫素越來越高,拍照

Android面試500:012如何在失真的條件下顯示一張超高清的圖片或者長圖?

1、通過計算BitmapFactory.Options 物件的inSamleSize 值 等比的壓縮圖片 。 2、使用WebView來載入該圖片; 3、使用MapView或者TileView來顯示圖片(類似地圖的機制);

java壓縮圖片記憶體大小,但改變解析度大小,第二種方式

/*** @Title: compressPic * @Description: 壓縮圖片,通過壓縮圖片質量,保持原圖大小* @param  quality:0-1    * @return byte[] * @throws*/public static byte[] co

android 壓縮圖片

將任意一張圖片壓縮成100*100的縮圖,並在ImageView上展示。 Bitmap bitmap = PicTool.decodeBitmapFromFile(tempFile.toString(),100,100); imageview.setImageBitmap

修復電腦圖片文件圖標顯示的方法

圖片圖片不顯示 修復 最近魅力網絡安裝了愛奇藝,發現愛奇藝自動安裝了個萬能播放器,打開圖片也是用那個打開的,默認關聯了圖片文件,後來卸載了愛奇藝,發現圖片文件的圖標不顯示了,看著很是不舒服為此只有手工更改了。 方法如下:我的電腦---文件夾選項---文件類型----點還原---高級---更改圖標---

Android 根據圖片資原始檔名獲取資源Id 的方法

一 .第一種方法 name 為檔名(不帶字尾名) . private int getDrawableRes(Context context, String name) { Str

PHP 圖片等比例縮放失真

<?php /** * 圖片等比例縮放類 * @author zhx */ class ImgThumbnail { private $source; private $imageinfo; private $image; private $perc

PHP實現將多個檔案壓縮成zip格式下載到本地的方法示例

本文例項講述了PHP實現將多個檔案壓縮成zip格式並下載到本地的方法。分享給大家供大家參考,具體如下:廢話不多說,直接上程式碼?123456789101112131415//這裡需要注意該目錄是否存在,並且有建立的許可權$zipname = 'path/test.zip'//

Android 5.0 自定義dialog 背景透明解決方法

在android 5.0 以上的版本中,自定義的dialog如果有圓角的話背景底部會出現白色,如圖: 解決方法是在style.xml檔案中定義一個dialog的樣式,程式碼如下: <s

適配:解決IE9以下對H5支援的方法

html5shiv:         解決ie9以下瀏覽器對html5新增標籤的不識別,並導致CSS不起作用的問題。 respond.min:       讓不支援css3 Media Query

C#生成縮圖失真方法

最近一個手持機專案有個需求,因為物料圖片的大小不一,有的很大顯示到手持機上會只顯示圖片的一部分,介面顯得非常亂,很影響客戶的體驗度。所以需要一個方法,將上傳到伺服器上的圖片進行處理,按照一定的大小格式進行儲存。 下面提供了兩種獲取圖片縮圖的方法,供大家參考。

Android一個TextView設定多種顏色的2種高效方法

有時候一個文字框為了強調內容需要顯示不同顏色,用以下程式碼可以輕鬆實現 方法一:(適用於顏色變化多的情況) //為文字框設定多種顏色 textView=(TextView)findViewBy

android實現一張或多張圖片壓縮保持清晰上傳

圖片過大,大於1M的情況下上傳伺服器會很耗時,因此要實現壓縮上傳並且不失真 String mCurrentPhotoPath; Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

如何壓縮圖片大小到100K以下

圖片太大怎麼辦?如何將圖片壓縮到100K以下,現在很多的網站對圖片的限制還是比較大的,有些網站圖片超過100K就不可以上傳,如果需要將圖片上傳,就需要將圖片壓縮到網站的規定大小,下面為大家介紹一下圖片壓縮到100K的方法。 1:在瀏覽器中找到這樣一個線上網站,進入到網站中可