1. 通過設置採樣率壓縮
res資源圖片壓縮 decodeResource
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.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;
return BitmapFactory.decodeResource(res, resId, options);
}
uri圖片壓縮 decodeStream
public static Bitmap decodeSampledBitmapFromUri(Uri uri, int reqWidth, int reqHeight) {
Bitmap bitmap = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
options.inSampleSize = BitmapUtils.calculateInSampleSize(options,
UtilUnitConversion.dip2px(MyApplication.mContext, reqWidth), UtilUnitConversion.dip2px(MyApplication.mContext, reqHeight));
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
本地File url圖片壓縮
public static Bitmap getloadlBitmap(String load_url, int width, int height) {
Bitmap bitmap = null;
if (!UtilText.isEmpty(load_url)) {
File file = new File(load_url);
if (file.exists()) {
FileInputStream fs = null;
try {
fs = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (null != fs) {
try {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fs.getFD(), null, opts);
opts.inDither = false;
opts.inPurgeable = true;
opts.inInputShareable = true;
opts.inTempStorage = new byte[32 * 1024];
opts.inSampleSize = BitmapUtils.calculateInSampleSize(opts,
UtilUnitConversion.dip2px(MyApplication.mContext, width), UtilUnitConversion.dip2px(MyApplication.mContext, height));
opts.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(),
null, opts);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fs) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
return bitmap;
}
根據顯示的圖片大小進行SampleSize的計算
public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
if (reqWidth == 0 || reqHeight == 0) {
return 1;
}
// 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;
}
附:寬高dp值轉px的工具類
/**
* dip 裝換成 px
*
* @作者 zhuofq
* @創建時間
* @param context
* @param dipValue
* @return int
*/
public static int dip2px(Context context, float dipValue) {
int num = 0;
if (context != null) {
final float scale = context.getResources().getDisplayMetrics().density;
num = (int) (dipValue * scale + 0.5f);
}
return num;
}
以上三種工具類的調用方式(設工具類名爲UtilBitmap,ImageView寬高100dp):
mImageView.setImageBitmap(UtilBitmap.decodeSampledBitmapFromResource(getResources(), R.id.myImage, 100, 100));
Bitmap bitmap = UtilBitmap.decodeSampledBitmapFromUri(cropFileUri, 100, 100);
mImageView.setImageBitmap(mContext, mImage,
UtilBitmap.getloadlBitmap(url, 100, 100),
R.drawable.ic_login_head, true);
2. 質量壓縮:指定圖片縮小到xkb以下
// 壓縮到100kb以下
int maxSize = 100 * 1024;
public static Bitmap getBitmapByte(Bitmap oriBitmap, int maxSize) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
oriBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
byte[] fileBytes = out.toByteArray();
int be = (maxSize * 100) / fileBytes.length;
if (be > 100) {
be = 100;
}
out.reset();
oriBitmap.compress(Bitmap.CompressFormat.JPEG, be, out);
return oriBitmap;
}
3. 單純獲取圖片寬高避免oom的辦法
itmapFactory.Options這個類,有一個字段叫做 inJustDecodeBounds 。SDK中對這個成員的說明是這樣的:
If set to true, the decoder will return null (no bitmap), but the out...
也就是說,如果我們把它設爲true,那麼BitmapFactory.decodeFile(String path, Options opt)並不會真的返回一個Bitmap給你,它僅僅會把它的寬,高取回來給你,這樣就不會佔用太多的內存,也就不會那麼頻繁的發生OOM了。
/**
* 根據res獲取Options,來獲取寬高options.outWidth和options.outHeight
* @param res
* @param resId
* @return
*/
public static BitmapFactory.Options decodeOptionsFromResource(Resources res, int resId) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
return options;
}