1 BitmapFactory.Options options = new BitmapFactory.Options();2 options.inSampleSize = 2;3 Bitmap img = BitmapFactory.decodeFile("/sdcard/1.png", options);
1 BitmapFactory.Options options = new BitmapFactory.Options();2 options.inPreferredConfig = Bitmap.Config.ARGB_4444; 3 Bitmap img = BitmapFactory.decodeFile("/sdcard/1.png", options);
Matrix matrix = new Matrix();float newWidth = 200;//图片放大后的宽度float newHeight = 300;//图片放大后的长度matrix.postScale(newWidth / img.getWidth(), newHeight/ img.getHeight());Bitmap img1 = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);//获得放大的图片img2 = img1.copy(Bitmap.Config.ARGB_4444, false);//获得ARGB_4444色彩模式的图片img = null;img1 = null;
尽量不要使用setImageBitmap或setImageResource 或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的, 需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法, 创建出一个bitmap,再将其设为ImageView的 source, decodeStream最大的秘密在于其直接调用 JNI >> nativeDecodeAsset() 来完成decode, 无需再使用java层的createBitmap,从而节省了java层的空间. 如果在读取时加上图片的Config参数,可以更有效减少加载的内存, 从而有效阻止抛出out of Memory异常 另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了. BitmapFactory.Options.inPreferredConfig ALPHA_8:数字为8,图形参数应该由一个字节来表示,应该是一种8位的位图 ARGB_4444:4+4+4+4=16,图形的参数应该由两个字节来表示,应该是一种16位的位图. ARGB_8888:8+8+8+8=32,图形的参数应该由四个字节来表示,应该是一种32位的位图. RGB_565:5+6+5=16,图形的参数应该由两个字节来表示,应该是一种16位的位图. ALPHA_8,ARGB_4444,ARGB_8888都是透明的位图,也就是所字母A代表透明. ARGB_4444:意味着有四个参数,即A,R,G,B,每一个参数由4bit表示. ARGB_8888:意味着有四个参数,即A,R,G,B,每一个参数由8bit来表示. RGB_565:意味着有三个参数,R,G,B,三个参数分别占5bit,6bit,5bit. BitmapFactory.Options.inPurgeable; 如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap 用于存储Pixel的内存空间在系统内存不足时可以被回收, 在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel), 系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组. 为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据. 在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收, 这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象, 不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同, 200个bitmap足以使大部分的设备重新OutOfMemory错误. 当isPurgable设为true时,系统中内存不足时, 可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误.
方法一:
/**
* 获取本地图片并指定高度和宽度
*/
public static Bitmap getNativeImage(String imagePath)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// 获取这个图片的宽和高
Bitmap myBitmap = BitmapFactory.decodeFile(imagePath, options); //此时返回myBitmap为空
//计算缩放比
int be = (int)(options.outHeight / (float)200);
int ys = options.outHeight % 200;//求余数
float fe = ys / (float)200;
if (fe >= 0.5)
be = be + 1;
if (be <= 0)
be = 1;
options.inSampleSize = be;
//重新读入图片,注意这次要把options.inJustDecodeBounds 设为 false
options.inJustDecodeBounds = false;
myBitmap = BitmapFactory.decodeFile(imagePath, options);
return myBitmap;
}
方法二:
/**
* 以最省内存的方式读取本地资源的图片
* @param context
* @param resId
* @return
*/
public static Bitmap readBitMap(Context context, int resId)
{
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
//获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
方法三:
/**
* 以最省内存的方式读取本地资源的图片 或者SDCard中的图片
* @param imagePath
* 图片在SDCard中的路径
* @return
*/
public static Bitmap getSDCardImg(String imagePath)
{
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
//获取资源图片
return BitmapFactory.decodeFile(imagePath, opt);
}