BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds =true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType;
注意上面中的options.inJustDecodeBounds =true的inJustDecodeBounds參數,爲了避免我翻譯的不準確我這裏先貼出來google的原文: 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。用我的話來說就是在decode的時候不給這個bitmap的像素區分配內存,除了這個區別Bitmap的其他信息你都能獲取到。這樣就有很大的意義,你既沒有消耗內存又拿到了圖片的信息,爲你下一步圖片處理提供幫助。
public static int calculateInSampleSize( BitmapFactory.Options options,int reqWidth,int reqHeight){ // Raw height and width of image finalint height = options.outHeight; finalint width = options.outWidth; int inSampleSize =1; if(height > reqHeight || width > reqWidth){ finalint halfHeight = height /2; finalint 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; }
在decode的時候先設置options.inJustDecodeBounds =true,獲取到圖片參數後再設置爲false,這就是decode時的技巧,下面就把完整代碼貼出來,可以作爲工具方法來使用:
public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId, int reqWidth,int reqHeight){ // First decode with inJustDecodeBounds=true to check dimensions finalBitmapFactory.Options options =newBitmapFactory.Options(); options.inJustDecodeBounds =true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds =false; returnBitmapFactory.decodeResource(res, resId, options); }
上面的方法來自於google官網,沒必要進行修改,這就是程序員的拿來主義吧,關鍵在於要知道爲什麼這麼寫。下面是我自己寫的一個方法可以直接拿來當工具用。
/** * 對圖片進行壓縮,主要是爲了解決控件顯示過大圖片佔用內存造成OOM問題,一般壓縮後的圖片大小應該和用來展示它的控件大小相近. * * @param context 上下文 * @param resId 圖片資源Id * @param reqWidth 期望壓縮的寬度 * @param reqHeight 期望壓縮的高度 * @return 壓縮後的圖片 */ public static Bitmap compressBitmapFromResourse(Context context, int resId, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); /* * 第一次解析時,inJustDecodeBounds設置爲true, * 禁止爲bitmap分配內存,雖然bitmap返回值爲空,但可以獲取圖片大小 */ options.inJustDecodeBounds = true; BitmapFactory.decodeResource(context.getResources(), resId, options); 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; } options.inSampleSize = inSampleSize; // 使用計算得到的inSampleSize值再次解析圖片 options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(context.getResources(), resId, options); }