一個好用的android圖片壓縮公用程式類

來源:互聯網
上載者:User

標籤:android   bitmap   


<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">用了很久圖片壓縮,之前人們一直使用google的官方圖片壓縮方法</span>


final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);


public static int calculateInSampleSize(            BitmapFactory.Options options, int reqWidth, int reqHeight) {    // Raw height and width of image    final int height = options.outHeight;    final int width = options.outWidth;    int inSampleSize = 1;    if (height > reqHeight || width > reqWidth) {        final int halfHeight = height / 2;        final int halfWidth = width / 2;        // Calculate the largest inSampleSize value that is a power of 2 and keeps both        // height and width larger than the requested height and width.        while ((halfHeight / inSampleSize) > reqHeight                && (halfWidth / inSampleSize) > reqWidth) {            inSampleSize *= 2;        }    }    return inSampleSize;}

代碼來自google 

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html


仔細看calucelateInSamplesize方法,該演算法返回的是一種壓縮比例,仔細一看他的計算過程,你會發現,inSampleSize的變化過程是2-4-8,,而真正進入wile迴圈時,寬高就已經被看成是小了一半來計算的了,所以,上面那個網站說12M能壓縮到0.75M,就是因為差距太大,如果安卓手機內部壓縮自己的圖片(大概是2M壓縮到100K),所以此時,這個方法就適用於android編碼壓縮了。

所以鄙人針對於android編碼時壓縮,在此對它進行了最佳化,最佳化後代碼如下:

運行:   culculateInSampleSize(bm,200,300)效果:

<pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">/**</span>
* 計算壓縮比例值(改進版 by touch_ping)

* 原版2>4>8...倍壓縮
* 當前2>3>4...倍壓縮

* @param options
*            解析圖片的配置資訊
* @param reqWidth
*            所需圖片壓縮尺寸最小寬度
* @param reqHeight
*            所需圖片壓縮尺寸最小高度
* @return
*/
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {

final int picheight = options.outHeight;
final int picwidth = options.outWidth;
Log.i("test", "原尺寸:" +  picwidth + "*" +picheight);

int targetheight = picheight;
int targetwidth = picwidth;
int inSampleSize = 1;

if (targetheight > reqHeight || targetwidth > reqWidth) {
while (targetheight  >= reqHeight
&& targetwidth>= reqWidth) {
Log.i("test","壓縮:" +inSampleSize + "倍");
inSampleSize += 1;
targetheight = picheight/inSampleSize;
targetwidth = picwidth/inSampleSize;
}
}

Log.i("test","最終壓縮比例:" +inSampleSize + "倍");
Log.i("test", "新尺寸:" +  targetwidth + "*" +targetheight);
return inSampleSize;
}



壓縮效果如下:


檔案大小從1.12M變成81.75k



最終附上完整壓縮公用程式類:

package com.example.mqtest;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.util.Log;/** * 圖片壓縮公用程式類 * @author touch_ping * 2015-1-5 下午1:29:59 */public class BitmapCompressor {/** * 品質壓縮 * @author ping 2015-1-5 下午1:29:58 * @param image * @param maxkb * @return */public static Bitmap compressBitmap(Bitmap image,int maxkb) {//L.showlog("壓縮圖片");ByteArrayOutputStream baos = new ByteArrayOutputStream();image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 品質壓縮方法,這裡100表示不壓縮,把壓縮後的資料存放到baos中int options = 100;//Log.i("test","原始大小" + baos.toByteArray().length);while (baos.toByteArray().length / 1024 > maxkb) { // 迴圈判斷如果壓縮後圖片是否大於(maxkb)50kb,大於繼續壓縮//Log.i("test","壓縮一次!");baos.reset();// 重設baos即清空baosoptions -= 10;// 每次都減少10image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 這裡壓縮options%,把壓縮後的資料存放到baos中}//Log.i("test","壓縮後大小" + baos.toByteArray().length);ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把壓縮後的資料baos存放到ByteArrayInputStream中Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream資料產生圖片return bitmap;}/** * http://developer.android.com/training/displaying-bitmaps/load-bitmap.html * 官網:擷取壓縮後的圖片 *  * @param res * @param resId * @param reqWidth *            所需圖片壓縮尺寸最小寬度 * @param reqHeight *            所需圖片壓縮尺寸最小高度 * @return */public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId, int reqWidth, int reqHeight) {final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);}/** * 官網:擷取壓縮後的圖片 *  * @param res * @param resId * @param reqWidth *            所需圖片壓縮尺寸最小寬度 * @param reqHeight *            所需圖片壓縮尺寸最小高度 * @return */public static Bitmap decodeSampledBitmapFromFile(String filepath,int reqWidth, int reqHeight) {final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(filepath, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeFile(filepath, options);}public static Bitmap decodeSampledBitmapFromBitmap(Bitmap bitmap,int reqWidth, int reqHeight) {ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.PNG, 90, baos);byte[] data = baos.toByteArray();final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeByteArray(data, 0, data.length, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeByteArray(data, 0, data.length, options);}/** * 計算壓縮比例值(改進版 by touch_ping) *  * 原版2>4>8...倍壓縮 * 當前2>3>4...倍壓縮 *  * @param options *            解析圖片的配置資訊 * @param reqWidth *            所需圖片壓縮尺寸最小寬度O * @param reqHeight *            所需圖片壓縮尺寸最小高度 * @return */public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {final int picheight = options.outHeight;final int picwidth = options.outWidth;Log.i("test", "原尺寸:" +  picwidth + "*" +picheight);int targetheight = picheight;int targetwidth = picwidth;int inSampleSize = 1;if (targetheight > reqHeight || targetwidth > reqWidth) {while (targetheight  >= reqHeight&& targetwidth>= reqWidth) {Log.i("test","壓縮:" +inSampleSize + "倍");inSampleSize += 1;targetheight = picheight/inSampleSize;targetwidth = picwidth/inSampleSize;}}Log.i("test","最終壓縮比例:" +inSampleSize + "倍");Log.i("test", "新尺寸:" +  targetwidth + "*" +targetheight);return inSampleSize;}}








public static int calculateInSampleSize(            BitmapFactory.Options options, int reqWidth, int reqHeight) {    // Raw height and width of image    final int height = options.outHeight;    final int width = options.outWidth;    int inSampleSize = 1;    if (height > reqHeight || width > reqWidth) {        final int halfHeight = height / 2;        final int halfWidth = width / 2;        // Calculate the largest inSampleSize value that is a power of 2 and keeps both        // height and width larger than the requested height and width.        while ((halfHeight / inSampleSize) > reqHeight                && (halfWidth / inSampleSize) > reqWidth) {            inSampleSize *= 2;        }    }    return inSampleSize;}

一個好用的android圖片壓縮公用程式類

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.