1. 程式人生 > >Android中處理大圖片時圖片壓縮

Android中處理大圖片時圖片壓縮

oca 內存空間 pan std ret bitmap sans source tar

1、BitmapFactory.Options中的屬性

在進行圖片壓縮時,是通過設置BitmapFactory.Options的一些值來改變圖片的屬性的,以下我們來看看BitmapFactory.Options中經常使用的屬性意思:

  • options.inPreferredConfig - 設置Bitmap的偏好配置。值有Bitmap.Config.ARGB_8888,Bitmap.Config.ARGB_4444,Bitmap.Config.ARGB_8888。Bitmap.Config.RGB_565。

    默覺得ARGB_8888,顧名思義。這是設置Bitmap的顯示質量的。

  • options.outHeight
    - 得到該Bitmap的高。
  • options.outWidth - 得到該Bitmap的寬。

  • options.outMimeType - 得到該Bitmap的MIME值。
  • options.inSampleSize - 壓縮比例。假設options.inSampleSize = 4;那麽壓縮後的圖片的寬和高都為原來圖片的1/4。壓縮後的圖片的像素為原來圖片的1/16。

  • options.inJustDecodeBounds - 官方文檔上是這樣介紹的:
      • If set to true, the decoder will return null (no bitmap), but
        the out... fields will still be set, allowing the caller to query

        the bitmap without having to allocate the memory for its pixels.
      • 意思就是:假設設置為true,那麽使用BitmapFactory.decodeStream(InputStream is, Rect outPadding,
        Options opts)或BitmapFactory.decodeXXX(....,Options opts)方法並不會真的返回一個Bitmap對象,而是返回null。盡管返回null,可是我們卻能夠通過options來獲得該Bitmap的一些值。如它的寬、高、MimeType等值。

        這樣就不必為Bitmap對象分配內存空間也能夠獲得它的Width和Height。從而節約內存。所以這個屬性對我們壓縮圖片前進行檢查大有幫助。經常使用的技巧就是為了避免圖片過大而導致OOM,所以在我們載入圖片之前就通過設置它為true,獲取到圖片的寬、高等值,然後進行一些推斷檢查等。決定圖片是否壓縮。我們來看看載入一張405x579圖片的樣例:

      • final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeResource(getResource(), R.mipmap.two, options);
        Log.v("zxy","bitmap="+bitmap);
        int height = options.outHeight;
        int width = options.outWidth;
        String mimeType = options.outMimeType;
        Log.v("zxy","mimeType="+mimeType+",height="+height+",width="+width);
        上述代碼輸出的是:技術分享能夠知道確實是返回null了。並且還獲得了該Bitmap的寬高等值。

2、通過實例來看看怎麽壓縮圖片

public class MainActivity extends ActionBarActivity {
    private ImageView mImageView, mResizeImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mImageView = (ImageView) findViewById(R.id.imageView);
        mResizeImageView = (ImageView) findViewById(R.id.resize_imageView);
        mImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.two));

        Bitmap bitmap = compressBitmap(getResources(), R.mipmap.two, 100, 100);
        Log.v("zxy", "compressBitmap,width=" + bitmap.getWidth() + ",height=" + bitmap.getHeight());
        mResizeImageView.setImageBitmap(bitmap);
    }

    /**
     * @param res Resource
     * @param resId 資源id
     * @param targetWidth 目標圖片的寬,單位px
     * @param targetHeight 目標圖片的高,單位px
     * @return 返回壓縮後的圖片的Bitmap
     */
    public Bitmap compressBitmap(Resources res, int resId, int targetWidth, int targetHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//設為true,節約內存
        BitmapFactory.decodeResource(res, resId, options);//返回null
        int height = options.outHeight;//得到源圖片height,單位px
        int width = options.outWidth;//得到源圖片的width。單位px
        //計算inSampleSize
        options.inSampleSize = calculateInSampleSize(width,height,targetWidth,targetHeight);
        options.inJustDecodeBounds = false;//設為false,能夠返回Bitmap
        return BitmapFactory.decodeResource(res,resId,options);
    }

    /**
     * 計算壓縮比例
     * @param width  源圖片的寬
     * @param height 源圖片的高
     * @param targetWidth  目標圖片的寬
     * @param targetHeight 目標圖片的高
     * @return inSampleSize 壓縮比例
     */
    public int calculateInSampleSize(int width,int height, int targetWidth, int targetHeight) {
        int inSampleSize = 1;
        if (height > targetHeight || width > targetWidth) {
            //計算圖片實際的寬高和目標圖片寬高的比率
            final int heightRate = Math.round((float) height / (float) targetHeight);
            final int widthRate = Math.round((float) width / (float) targetWidth);
            //選取最小的比率作為inSampleSize
            inSampleSize = heightRate < widthRate ? heightRate : widthRate;
        }
        return inSampleSize;
    }
}
我們通過看Log能夠知道壓縮後圖片的寬高:

技術分享
我們再看看效果圖:

技術分享

Android中處理大圖片時圖片壓縮