BitmapFactory.Options中有以下属性:
inBitmap——在解析Bitmap时重用该Bitmap,不过必须等大的Bitmap而且inMutable须为true
inMutable——配置Bitmap是否可以更改,比如:在Bitmap上隔几个像素加一条线段
inJustDecodeBounds——为true仅返回Bitmap的宽高等属性
inSampleSize——须>=1,表示Bitmap的压缩比例,如:inSampleSize=4,将返回一个是原始图的1/16大小的Bitmap
inPreferredConfig——Bitmap.Config.ARGB_8888等
inDither——是否抖动,默认为false
inPremultiplied——默认为true,一般不改变它的值
inDensity——Bitmap的像素密度
inTargetDensity——Bitmap最终的像素密度
inScreenDensity——当前屏幕的像素密度
inScaled——是否支持缩放,默认为true,当设置了这个,Bitmap将会以inTargetDensity的值进行缩放
inPurgeable——当存储Pixel的内存空间在系统内存不足时是否可以被回收
inInputShareable——inPurgeable为true情况下才生效,是否可以共享一个InputStream
inPreferQualityOverSpeed——为true则优先保证Bitmap质量其次是解码速度
outWidth——返回的Bitmap的宽
outHeight——返回的Bitmap的高
inTempStorage——解码时的临时空间,建议16*1024
2.2、优化策略
1、BitmapConfig的配置
2、使用decodeFile、decodeResource、decodeStream进行解析Bitmap时,配置inDensity和inTargetDensity,两者应该相等,值可以等于屏幕像素密度*0.75f
3、使用inJustDecodeBounds预判断Bitmap的大小及使用inSampleSize进行压缩
4、对Density>240的设备进行Bitmap的适配(缩放Density)
5、2.3版本inNativeAlloc的使用
6、4.4以下版本inPurgeable、inInputShareable的使用
7、Bitmap的回收
针对上面方案,把Bitmap解码的代码封装成了一个工具类,如下:
public class BitmapDecodeUtil {
private static final int DEFAULT_DENSITY = 240;
private static final float SCALE_FACTOR = 0.75f;
private static final Bitmap.Config DEFAULT_BITMAP_CONFIG = Bitmap.Config.RGB_565;
private static BitmapFactory.Options getBitmapOptions(Context context) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = true;
options.inPreferredConfig = DEFAULT_BITMAP_CONFIG;
options.inPurgeable = true;
options.inInputShareable = true;
options.inJustDecodeBounds = false;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
Field field = null;
try {
field = BitmapFactory.Options.class.getDeclaredField("inNativeAlloc");
field.setAccessible(true);
field.setBoolean(options, true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
int displayDensityDpi = context.getResources().getDisplayMetrics().densityDpi;
float displayDensity = context.getResources().getDisplayMetrics().density;
if (displayDensityDpi > DEFAULT_DENSITY && displayDensity > 1.5f) {
int density = (int) (displayDensityDpi * SCALE_FACTOR);
options.inDensity = density;
options.inTargetDensity = density;
}
return options;
}
public static Bitmap decodeBitmap(Context context, int resId) {
checkParam(context);
return BitmapFactory.decodeResource(context.getResources(), resId, getBitmapOptions(context));
}
public static Bitmap decodeBitmap(Context context, String pathName) {
checkParam(context);
return BitmapFactory.decodeFile(pathName, getBitmapOptions(context));
}
public static Bitmap decodeBitmap(Context context, InputStream is) {
checkParam(context);
checkParam(is);
return BitmapFactory.decodeStream(is, null, getBitmapOptions(context));
}
public static Bitmap compressBitmap(Context context,int resId, int maxWidth, int maxHeight) {
checkParam(context);
final TypedValue value = new TypedValue();
InputStream is = null;
try {
is = context.getResources().openRawResource(resId, value);
return compressBitmap(context, is, maxWidth, maxHeight);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static Bitmap compressBitmap(Context context, String pathName, int maxWidth, int maxHeight) {
checkParam(context);
InputStream is = null;
try {
is = new FileInputStream(pathName);
return compressBitmap(context, is, maxWidth, maxHeight);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static Bitmap compressBitmap(Context context, InputStream is, int maxWidth, int maxHeight) {
checkParam(context);
checkParam(is);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, opt);
int height = opt.outHeight;
int width = opt.outWidth;
int sampleSize = computeSampleSize(width, height, maxWidth, maxHeight);
BitmapFactory.Options options = getBitmapOptions(context);
options.inSampleSize = sampleSize;
return BitmapFactory.decodeStream(is, null, options);
}
private static int computeSampleSize(int width, int height, int maxWidth, int maxHeight) {
int inSampleSize = 1;
if (height > maxHeight || width > maxWidth) {
final int heightRate = Math.round((float) height / (float) maxHeight);
final int widthRate = Math.round((float) width / (float) maxWidth);
inSampleSize = heightRate < widthRate ? heightRate : widthRate;
}
if (inSampleSize % 2 != 0) {
inSampleSize -= 1;
}
return inSampleSize <= 1 ? 1 : inSampleSize;
}
private static <T> void checkParam(T param){
if(param == null)
throw new NullPointerException();
}
}
https://www.cnblogs.com/chenliyang/p/6559477.html